{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "eaecf756-395f-42bb-94cd-8a74e4d3c9a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "%pylab is deprecated, use %matplotlib inline and import the required libraries.\n",
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1ad179ba8d0>]"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%pylab inline \n",
    "import matplotlib.pyplot as plt \n",
    "import numpy as np\n",
    "plt.plot(np.sin(np.linspace(0,2*np.pi, 100)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d27d2b53-71cc-4be5-9d58-6402c3af3c58",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test set size: 10000\n",
      "Training set size: 60000\n",
      "Number of training samples: 43360\n",
      "Number of cross-validation samples: 10850\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "label_size = 18 # Label size\n",
    "ticklabel_size = 14 # Tick label size\n",
    "\n",
    "class FlattenTransform:\n",
    "    def __call__(self, tensor):\n",
    "        ''' \n",
    "        Flatten tensor into an 1-D vector\n",
    "        '''\n",
    "        return tensor.view(-1)\n",
    "    \n",
    "# Define a transform to normalize the data\n",
    "transform = transforms.Compose([\n",
    "    transforms.ToTensor(),\n",
    "    FlattenTransform()\n",
    "])\n",
    "\n",
    "# Load test data from the MNIST\n",
    "testset = torchvision.datasets.MNIST(root='./Data', train=False, download=False, transform=transform)\n",
    "print(f\"Test set size: {len(testset)}\")\n",
    "\n",
    "# Load training data from the MNIST\n",
    "trainset = torchvision.datasets.MNIST(root='./Data', train=True, download=False, transform=transform)\n",
    "print(f\"Training set size: {len(trainset)}\")\n",
    "\n",
    "# Rate of trX and cvX\n",
    "tr_cv_rate = 0.8\n",
    "\n",
    "# Create a list to store indices for each class\n",
    "class_indices = [[] for _ in range(10)]  # 10 classes in MNIST\n",
    "\n",
    "# Populate class_indices\n",
    "for idx, (_, label) in enumerate(trainset):\n",
    "    class_indices[label].append(idx)\n",
    "\n",
    "# Calculate the number of samples for each class in training and validation sets\n",
    "train_size_per_class = int(tr_cv_rate * min(len(indices) for indices in class_indices))\n",
    "val_size_per_class = min(len(indices) for indices in class_indices) - train_size_per_class\n",
    "\n",
    "# Create balanced train and validation sets\n",
    "train_indices = []\n",
    "val_indices = []\n",
    "for indices in class_indices:\n",
    "    train_indices.extend(indices[:train_size_per_class])\n",
    "    val_indices.extend(indices[train_size_per_class:train_size_per_class + val_size_per_class])\n",
    "\n",
    "# Create Subset datasets\n",
    "from torch.utils.data import Subset\n",
    "trX = Subset(trainset, train_indices)\n",
    "cvX = Subset(trainset, val_indices)\n",
    "\n",
    "print(f\"Number of training samples: {len(trX)}\")\n",
    "print(f\"Number of cross-validation samples: {len(cvX)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ffa366ff-5507-4539-8a16-cc746903c461",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Input_size is 784\n",
      "tensor([[0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]])\n"
     ]
    }
   ],
   "source": [
    "batch_size = 42 # Define training batch\n",
    "\n",
    "def one_hot_collate(batch):\n",
    "    data = torch.stack([item[0] for item in batch])\n",
    "    labels = torch.tensor([item[1] for item in batch])\n",
    "    one_hot_labels = torch.zeros(labels.size(0), 10)  # 10 classes in MNIST\n",
    "    one_hot_labels.scatter_(1, labels.unsqueeze(1), 1)\n",
    "    return data, one_hot_labels\n",
    "\n",
    "trLoader = torch.utils.data.DataLoader(trX, batch_size=batch_size, shuffle=True, num_workers=0, collate_fn=one_hot_collate)\n",
    "cvLoader = torch.utils.data.DataLoader(cvX, batch_size=batch_size, shuffle=False, num_workers=0, collate_fn=one_hot_collate)\n",
    "teLoader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=0, collate_fn=one_hot_collate)\n",
    "\n",
    "# Get a batch of training data\n",
    "dataiter = iter(trLoader)\n",
    "data, labels = next(dataiter)\n",
    "\n",
    "input_size = data[0].numpy().shape[0]\n",
    "print(f'Input_size is {input_size}')\n",
    "print(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7fe08623-2263-4b98-be00-f1a6a80c2a0e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "FNN(\n",
      "  (fc1): Linear(in_features=784, out_features=10, bias=True)\n",
      "  (relu1): ReLU()\n",
      "  (fc2): Linear(in_features=10, out_features=10, bias=True)\n",
      "  (relu2): ReLU()\n",
      "  (fc3): Linear(in_features=10, out_features=10, bias=True)\n",
      "  (softmax): Softmax(dim=1)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "\n",
    "class FNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size, num_classes):\n",
    "        super(FNN, self).__init__()\n",
    "        self.fc1 = nn.Linear(input_size, hidden_size)\n",
    "        self.relu1 = nn.ReLU()\n",
    "        self.fc2 = nn.Linear(hidden_size, hidden_size)\n",
    "        self.relu2 = nn.ReLU()\n",
    "        self.fc3 = nn.Linear(hidden_size, num_classes)\n",
    "        self.softmax = nn.Softmax(dim=1)\n",
    "    \n",
    "    def forward(self, x):\n",
    "        x = self.fc1(x)\n",
    "        x = self.relu1(x)\n",
    "        x = self.fc2(x)\n",
    "        x = self.relu2(x)\n",
    "        x = self.fc3(x)\n",
    "        out = self.softmax(x)\n",
    "        return out\n",
    "\n",
    "# Define the model parameters\n",
    "hidden_size = 10\n",
    "num_classes = 10  # MNIST has 10 classes (digits 0-9)\n",
    "\n",
    "# Instantiate the model\n",
    "model = FNN(input_size, hidden_size, num_classes)\n",
    "print(model)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bea61822-73c1-4318-83ee-282bb1abe63d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/50], Train Loss: 1.8046, CV Loss: 1.6758\n",
      "Epoch [2/50], Train Loss: 1.6592, CV Loss: 1.6578\n",
      "Epoch [3/50], Train Loss: 1.6450, CV Loss: 1.6503\n",
      "Epoch [4/50], Train Loss: 1.6375, CV Loss: 1.6439\n",
      "Epoch [5/50], Train Loss: 1.6324, CV Loss: 1.6403\n",
      "Epoch [6/50], Train Loss: 1.6285, CV Loss: 1.6376\n",
      "Epoch [7/50], Train Loss: 1.6251, CV Loss: 1.6352\n",
      "Epoch [8/50], Train Loss: 1.6228, CV Loss: 1.6337\n",
      "Epoch [9/50], Train Loss: 1.6203, CV Loss: 1.6314\n",
      "Epoch [10/50], Train Loss: 1.6184, CV Loss: 1.6294\n",
      "Epoch [11/50], Train Loss: 1.6171, CV Loss: 1.6288\n",
      "Epoch [12/50], Train Loss: 1.6160, CV Loss: 1.6268\n",
      "Epoch [13/50], Train Loss: 1.6139, CV Loss: 1.6257\n",
      "Epoch [14/50], Train Loss: 1.6127, CV Loss: 1.6239\n",
      "Epoch [15/50], Train Loss: 1.6116, CV Loss: 1.6245\n",
      "Epoch [16/50], Train Loss: 1.6107, CV Loss: 1.6232\n",
      "Epoch [17/50], Train Loss: 1.6097, CV Loss: 1.6221\n",
      "Epoch [18/50], Train Loss: 1.6089, CV Loss: 1.6207\n",
      "Epoch [19/50], Train Loss: 1.6078, CV Loss: 1.6210\n",
      "Epoch [20/50], Train Loss: 1.6068, CV Loss: 1.6225\n",
      "Epoch [21/50], Train Loss: 1.6060, CV Loss: 1.6220\n",
      "Epoch [22/50], Train Loss: 1.6056, CV Loss: 1.6177\n",
      "Epoch [23/50], Train Loss: 1.6045, CV Loss: 1.6180\n",
      "Epoch [24/50], Train Loss: 1.6038, CV Loss: 1.6190\n",
      "Epoch [25/50], Train Loss: 1.6030, CV Loss: 1.6186\n",
      "Epoch [26/50], Train Loss: 1.6026, CV Loss: 1.6183\n",
      "Epoch [27/50], Train Loss: 1.6016, CV Loss: 1.6175\n",
      "Epoch [28/50], Train Loss: 1.6012, CV Loss: 1.6189\n",
      "Epoch [29/50], Train Loss: 1.6009, CV Loss: 1.6172\n",
      "Epoch [30/50], Train Loss: 1.6004, CV Loss: 1.6173\n",
      "Epoch [31/50], Train Loss: 1.5999, CV Loss: 1.6161\n",
      "Epoch [32/50], Train Loss: 1.5991, CV Loss: 1.6157\n",
      "Epoch [33/50], Train Loss: 1.5986, CV Loss: 1.6162\n",
      "Epoch [34/50], Train Loss: 1.5981, CV Loss: 1.6156\n",
      "Epoch [35/50], Train Loss: 1.5974, CV Loss: 1.6167\n",
      "Epoch [36/50], Train Loss: 1.5970, CV Loss: 1.6158\n",
      "Epoch [37/50], Train Loss: 1.5965, CV Loss: 1.6171\n",
      "Epoch [38/50], Train Loss: 1.5962, CV Loss: 1.6165\n",
      "Epoch [39/50], Train Loss: 1.5964, CV Loss: 1.6152\n",
      "Epoch [40/50], Train Loss: 1.5955, CV Loss: 1.6143\n",
      "Epoch [41/50], Train Loss: 1.5952, CV Loss: 1.6170\n",
      "Epoch [42/50], Train Loss: 1.5949, CV Loss: 1.6147\n",
      "Epoch [43/50], Train Loss: 1.5942, CV Loss: 1.6137\n",
      "Epoch [44/50], Train Loss: 1.5946, CV Loss: 1.6142\n",
      "Epoch [45/50], Train Loss: 1.5939, CV Loss: 1.6146\n",
      "Epoch [46/50], Train Loss: 1.5942, CV Loss: 1.6160\n",
      "Epoch [47/50], Train Loss: 1.5932, CV Loss: 1.6146\n",
      "Epoch [48/50], Train Loss: 1.5932, CV Loss: 1.6138\n",
      "Epoch [49/50], Train Loss: 1.5932, CV Loss: 1.6140\n",
      "Epoch [50/50], Train Loss: 1.5929, CV Loss: 1.6150\n"
     ]
    }
   ],
   "source": [
    "# Define loss function and optimizer\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = torch.optim.Adam(model.parameters())\n",
    "\n",
    "# Lists to store losses\n",
    "train_losses = []\n",
    "cv_losses = []\n",
    "\n",
    "# Number of epochs\n",
    "num_epochs = 50\n",
    "\n",
    "for epoch in range(num_epochs):\n",
    "    model.train()\n",
    "    batch_losses = []\n",
    "    \n",
    "    for batch_x, batch_y in trLoader:\n",
    "        # Forward pass\n",
    "        outputs = model(batch_x)\n",
    "        loss = criterion(outputs, batch_y)\n",
    "        \n",
    "        # Backward pass and optimize\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "        batch_losses.append(loss.item())\n",
    "    \n",
    "    # Calculate average training loss for this epoch\n",
    "    avg_train_loss = sum(batch_losses) / len(batch_losses)\n",
    "    train_losses.append(avg_train_loss)\n",
    "    \n",
    "    # Evaluate on cross-validation set\n",
    "    model.eval()\n",
    "    cv_batch_losses = []\n",
    "    with torch.no_grad():\n",
    "        for cv_x, cv_y in cvLoader:\n",
    "            cv_outputs = model(cv_x)\n",
    "            cv_loss = criterion(cv_outputs, cv_y)\n",
    "            cv_batch_losses.append(cv_loss.item())\n",
    "    \n",
    "    avg_cv_loss = sum(cv_batch_losses) / len(cv_batch_losses)\n",
    "    cv_losses.append(avg_cv_loss)\n",
    "    \n",
    "    print(f'Epoch [{epoch+1}/{num_epochs}], Train Loss: {avg_train_loss:.4f}, CV Loss: {avg_cv_loss:.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "a03bf85e-1a81-4936-bce9-2e6106982e10",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on training set: 87.00%\n",
      "Accuracy on cross-validation set: 84.54%\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1cAAAHUCAYAAADWedKvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB4LklEQVR4nO3dd3hUVf7H8c9Mykx6gZACSehdmggC0gSlKIKioKKCoq6KbS3rYgPXwtrRVXFdRWyrqAjrz4I0BRVcQY26igrSIZES0pPJJHN/f9yZSYYECEnIZML79Tz3mZl779w5k1yQj+ec77EYhmEIAAAAAFAnVn83AAAAAACaAsIVAAAAANQDwhUAAAAA1APCFQAAAADUA8IVAAAAANQDwhUAAAAA1APCFQAAAADUA8IVAAAAANQDwhUAAAAA1APCFYAThsViqdH22Wef1elzZs+eLYvFUqv3fvbZZ/XShsZu2rRpat26dY3Odblceu211zRy5Eg1b95cISEhatGihc4++2z93//9n1wu1/FtbB19//33slgs+utf/3rYczZt2iSLxaIbb7yxxtet7j4bNmyYhg0bdtT3btu2TRaLRQsWLKjx53n8/PPPmj17trZt21bl2LH8XuubxWLR9ddf75fPBgCPYH83AAAayrp163xe33///fr000+1atUqn/1du3at0+dceeWVGj16dK3e26dPH61bt67ObWgqSkpKNGHCBC1btkwXXnih5s2bp6SkJO3bt09Lly7VBRdcoIULF2r8+PH+buph9ezZUyeffLJeffVVPfjggwoKCqpyzssvvyxJmj59ep0+67nnnqvT+2vi559/1n333adhw4ZVCVL33HOPbrrppuPeBgBorAhXAE4Yp556qs/rhIQEWa3WKvsPVVRUpPDw8Bp/TqtWrdSqVatatTE6Ovqo7TmR3HLLLfrkk0/0yiuv6LLLLvM5dt555+n2229XcXHxYd/vdDplsVgUHOzf/9xNnz5d1113nT7++GOdffbZPsfKy8v16quv6uSTT1bPnj3r9Dn+DuXt2rXz6+cDgL8xLBAAKhk2bJi6d++uNWvWaODAgQoPD9cVV1whSVq4cKHOPPNMJScnKywsTF26dNFf//pXFRYW+lyjuuFarVu31tlnn62lS5eqT58+CgsLU+fOnTV//nyf86obFjht2jRFRkZq8+bNGjt2rCIjI5Wamqpbb71VDofD5/27du3S+eefr6ioKMXGxmrKlClav359jYaA7du3T9ddd526du2qyMhItWjRQqeffro+//xzn/M8Q8oee+wxPfHEE2rTpo0iIyM1YMAAffXVV1Wuu2DBAnXq1Ek2m01dunTRq6++esR2eGRlZenFF1/UqFGjqgQrjw4dOqhHjx6SKn52r732mm699Va1bNlSNptNmzdvliTNnz9fPXv2lN1uV3x8vM4991xt3LjR53pbtmzRhRdeqJSUFNlsNiUmJmrEiBHKyMjwnrNq1SoNGzZMzZo1U1hYmNLS0jRx4kQVFRUd9rtcfPHFCgsL8/ZQVbZs2TLt3r37mO+z6lQ3LHDPnj2aNGmSoqKiFBMTo8mTJysrK6vKezds2KALL7xQrVu3VlhYmFq3bq2LLrpI27dv956zYMECXXDBBZKk4cOHe4fSeu6t6oYFlpSUaObMmWrTpo1CQ0PVsmVLzZgxQzk5OT7n1fTPSF1kZ2fruuuuU8uWLRUaGqq2bdvqrrvuqvLn6J133lH//v0VExOj8PBwtW3b1vv7kcyhqg888IA6deqksLAwxcbGqkePHnrqqafqra0AAhM9VwBwiMzMTF1yySX6y1/+ooceekhWq/n/oTZt2qSxY8fq5ptvVkREhH755Rc9/PDD+vrrr6sMLazO999/r1tvvVV//etflZiYqBdffFHTp09X+/btNWTIkCO+1+l06pxzztH06dN16623as2aNbr//vsVExOje++9V5JUWFio4cOHKzs7Ww8//LDat2+vpUuXavLkyTX63tnZ2ZKkWbNmKSkpSQUFBVq8eLGGDRumlStXVvlH+7PPPqvOnTtr7ty5kswhYWPHjtXWrVsVExMjyfzH+OWXX67x48fr8ccfV25urmbPni2Hw+H9uR7Op59+KqfTqQkTJtSo/R4zZ87UgAED9Pzzz8tqtapFixaaM2eO7rzzTl100UWaM2eODhw4oNmzZ2vAgAFav369OnToIEkaO3asysvL9cgjjygtLU379+/X2rVrvUFg27ZtOuusszR48GDNnz9fsbGx2r17t5YuXarS0tLD9nDGxMRo4sSJWrhwofbt26eEhATvsZdffll2u10XX3yxpLrfZ5UVFxdr5MiR2rNnj+bMmaOOHTvqww8/rPae2LZtmzp16qQLL7xQ8fHxyszM1Lx583TKKafo559/VvPmzXXWWWfpoYce0p133qlnn31Wffr0kXT4HivDMDRhwgStXLlSM2fO1ODBg/XDDz9o1qxZWrdundatWyebzeY9vy5/Ro6mpKREw4cP1++//6777rtPPXr00Oeff645c+YoIyNDH374oSRz+PDkyZM1efJkzZ49W3a7Xdu3b/f52T/yyCOaPXu27r77bg0ZMkROp1O//PJLlcAI4ARkAMAJaurUqUZERITPvqFDhxqSjJUrVx7xvS6Xy3A6ncbq1asNScb333/vPTZr1izj0L9e09PTDbvdbmzfvt27r7i42IiPjzf+9Kc/efd9+umnhiTj008/9WmnJOPtt9/2uebYsWONTp06eV8/++yzhiTj448/9jnvT3/6kyHJePnll4/4nQ5VVlZmOJ1OY8SIEca5557r3b9161ZDknHSSScZZWVl3v1ff/21Icl48803DcMwjPLyciMlJcXo06eP4XK5vOdt27bNCAkJMdLT04/4+X//+98NScbSpUtr1F7Pz27IkCE++w8ePGiEhYUZY8eO9dm/Y8cOw2azGRdffLFhGIaxf/9+Q5Ixd+7cw37Gu+++a0gyMjIyatSm6tr3xBNPePcdOHDAsNlsxpQpU6p9z7HeZ0OHDjWGDh3qfT1v3jxDkvGf//zH57yrrrrqqPdEWVmZUVBQYERERBhPPfWUd/8777xT5R71mDp1qs/vdenSpYYk45FHHvE5b+HChYYk44UXXvDuq+mfkcORZMyYMeOwx59//vlq/xw9/PDDhiRj2bJlhmEYxmOPPWZIMnJycg57rbPPPtvo1avXUdsE4MTDsEAAOERcXJxOP/30Kvu3bNmiiy++WElJSQoKClJISIiGDh0qSVWGl1WnV69eSktL87622+3q2LGjz7Crw7FYLBo3bpzPvh49evi8d/Xq1YqKiqpSTOOiiy466vU9nn/+efXp00d2u13BwcEKCQnRypUrq/1+Z511lk9xBs/wPE+bfv31V+3Zs0cXX3yxzzDJ9PR0DRw4sMZtOlYTJ070eb1u3ToVFxdr2rRpPvtTU1N1+umna+XKlZKk+Ph4tWvXTo8++qieeOIJfffdd1UqEfbq1UuhoaG6+uqr9corr2jLli1VPr+8vFxlZWXezXONoUOHql27dj5DA9944w05HA6fIWd1vc8q+/TTTxUVFaVzzjnHZ7+nl6yygoIC3XHHHWrfvr2Cg4MVHBysyMhIFRYWHvPnenh6ew792V9wwQWKiIjw/uw96vJnpCZtiYiI0Pnnn++z39M2T1tOOeUUSdKkSZP09ttva/fu3VWu1a9fP33//fe67rrr9MknnygvL6/O7QPQNBCuAOAQycnJVfYVFBRo8ODB+u9//6sHHnhAn332mdavX6/33ntPko5YVMGjWbNmVfbZbLYavTc8PFx2u73Ke0tKSryvDxw4oMTExCrvrW5fdZ544glde+216t+/vxYtWqSvvvpK69ev1+jRo6tt46HfxzO8y3PugQMHJElJSUlV3lvdvkN5/pG9devWGrXf49Dfn6cd1f1eU1JSvMctFotWrlypUaNG6ZFHHlGfPn2UkJCgG2+8Ufn5+ZLM4W8rVqxQixYtNGPGDLVr107t2rXzmWszYsQIhYSEeDdPcLJYLLriiiv0448/asOGDZLMIYFt2rTR8OHDJdXPfXbod6/u91/dz//iiy/WM888oyuvvFKffPKJvv76a61fv14JCQnH/LmVPz84ONhnGKRk/iySkpK8P3uPuvwZqUlbkpKSqsyHbNGihYKDg71tGTJkiJYsWaKysjJddtllatWqlbp3764333zT+56ZM2fqscce01dffaUxY8aoWbNmGjFihPf3CuDExZwrADhEdWtUrVq1Snv27NFnn33m7UWQ1KjmWDRr1kxff/11lf3VFS+ozuuvv65hw4Zp3rx5Pvs9waI27Tnc59ekTcOHD1dISIiWLFmia665psafe+jvz9OOzMzMKufu2bNHzZs3975OT0/XSy+9JEn67bff9Pbbb2v27NkqLS3V888/L0kaPHiwBg8erPLycm3YsEH/+Mc/dPPNNysxMVEXXnih/vnPf/r8zCpff9q0abr33ns1f/58hYSE6LvvvtP999/vbXN932c1vSdyc3P1wQcfaNasWT7rcTkcDu9cvNp+fllZWZV5ZoZhKCsry9tL1BCaNWum//73vzIMw+ce2bt3r8rKynx+T+PHj9f48ePlcDj01Vdfac6cObr44ovVunVrDRgwQMHBwbrlllt0yy23KCcnRytWrNCdd96pUaNGaefOncdUXRRA00LPFQDUgOcfY5Un30vSP//5T380p1pDhw5Vfn6+Pv74Y5/9b731Vo3eb7FYqny/H374ocr6YDXVqVMnJScn680335RhGN7927dv19q1a4/6/qSkJG8vyuEqDP7+++/64YcfjnidAQMGKCwsTK+//rrP/l27dmnVqlUaMWJEte/r2LGj7r77bp100kn69ttvqxwPCgpS//799eyzz0qS95xOnTqpb9++3q1y9byUlBSNHj1ab775pp599llZrVZNnTrVe7y+77Phw4crPz9f77//vs/+f//73z6vLRaLDMOo8rkvvviiysvLffYd2kN5JJ6f7aE/+0WLFqmwsPCwP/vjYcSIESooKNCSJUt89nvureraYrPZNHToUD388MOSpO+++67KObGxsTr//PM1Y8YMZWdnV7u4MoATBz1XAFADAwcOVFxcnK655hrNmjVLISEheuONN/T999/7u2leU6dO1ZNPPqlLLrlEDzzwgNq3b6+PP/5Yn3zyiSQdtTrf2Wefrfvvv1+zZs3S0KFD9euvv+pvf/ub2rRpo7KysmNuj9Vq1f33368rr7xS5557rq666irl5ORo9uzZNRoWKJlDFbds2aJp06bpk08+0bnnnqvExETt379fy5cv18svv6y33nrLO9+rOrGxsbrnnnt055136rLLLtNFF12kAwcO6L777pPdbtesWbMkmUHy+uuv1wUXXKAOHTooNDRUq1at0g8//ODtzXn++ee1atUqnXXWWUpLS1NJSYm3VPjIkSNr9J2mT5+uDz/80FtmPjU11Xusvu+zyy67TE8++aQuu+wyPfjgg+rQoYM++ugj7z3hER0drSFDhujRRx9V8+bN1bp1a61evVovvfSSYmNjfc7t3r27JOmFF15QVFSU7Ha72rRpU+2QvjPOOEOjRo3SHXfcoby8PA0aNMhbLbB379669NJLa/W9Duf333/Xu+++W2V/165dddlll+nZZ5/V1KlTtW3bNp100kn64osv9NBDD2ns2LHe39+9996rXbt2acSIEWrVqpVycnL01FNP+cx9GzdunLp3766+ffsqISFB27dv19y5c5Wenu6tPAngBOXfehoA4D+HqxbYrVu3as9fu3atMWDAACM8PNxISEgwrrzySuPbb7+tUnXtcNUCzzrrrCrXPLS62+GqBR7azsN9zo4dO4zzzjvPiIyMNKKiooyJEycaH330UbUV4w7lcDiM2267zWjZsqVht9uNPn36GEuWLKlSAc5TLfDRRx+tcg1JxqxZs3z2vfjii0aHDh2M0NBQo2PHjsb8+fOrXPNIysrKjFdeecU4/fTTjfj4eCM4ONhISEgwxowZY/z73/82ysvLDcOo+Nm988471V7nxRdfNHr06GGEhoYaMTExxvjx442ffvrJe/yPP/4wpk2bZnTu3NmIiIgwIiMjjR49ehhPPvmktyriunXrjHPPPddIT083bDab0axZM2Po0KHG+++/X6PvYhiGUVpaaiQmJlZbuc4w6nafHXo/GYZh7Nq1y5g4caLPPbF27doq1/OcFxcXZ0RFRRmjR482/ve//xnp6enG1KlTfa45d+5co02bNkZQUJDPdar7vRYXFxt33HGHkZ6eboSEhBjJycnGtddeaxw8eNDnvJr+GTkcSYfdPPfkgQMHjGuuucZITk42goODjfT0dGPmzJlGSUmJ9zoffPCBMWbMGKNly5ZGaGio0aJFC2Ps2LHG559/7j3n8ccfNwYOHGg0b97cCA0NNdLS0ozp06cb27ZtO2o7ATRtFsOoNFYDANDkPPTQQ7r77ru1Y8cOtWrVyt/NAQCgyWJYIAA0Ic8884wkqXPnznI6nVq1apWefvppXXLJJQQrAACOM8IVADQh4eHhevLJJ7Vt2zY5HA6lpaXpjjvu0N133+3vpgEA0OQxLBAAAAAA6gGl2AEAAACgHhCuAAAAAKAeEK4AAAAAoB5Q0KIaLpdLe/bsUVRUlCwWi7+bAwAAAMBPDMNQfn6+UlJSZLUeuW+KcFWNPXv2KDU11d/NAAAAANBI7Ny586jLmhCuqhEVFSXJ/AFGR0f7uTUAAAAA/CUvL0+pqanejHAkhKtqeIYCRkdHE64AAAAA1Gi6EAUtAAAAAKAeEK4AAAAAoB4QrgAAAACgHjDnCgAA4ARnGIbKyspUXl7u76YAfhESEqKgoKA6X4dwBQAAcAIrLS1VZmamioqK/N0UwG8sFotatWqlyMjIOl2HcAUAAHCCcrlc2rp1q4KCgpSSkqLQ0NAaVUQDmhLDMLRv3z7t2rVLHTp0qFMPFuEKAADgBFVaWiqXy6XU1FSFh4f7uzmA3yQkJGjbtm1yOp11ClcUtAAAADjBWa38kxAntvrqseVPEgAAAADUA8IVAAAAANQDwhUAAABOeMOGDdPNN99c4/O3bdsmi8WijIyM49YmBB7CFQAAAAKGxWI54jZt2rRaXfe9997T/fffX+PzU1NTlZmZqe7du9fq82qKEBdYqBYIAACAgJGZmel9vnDhQt1777369ddfvfvCwsJ8znc6nQoJCTnqdePj44+pHUFBQUpKSjqm96Dpo+eqkfvXmi0a9eQavfj5Fn83BQAANHGGYaiotMwvm2EYNWpjUlKSd4uJiZHFYvG+LikpUWxsrN5++20NGzZMdrtdr7/+ug4cOKCLLrpIrVq1Unh4uE466SS9+eabPtc9dFhg69at9dBDD+mKK65QVFSU0tLS9MILL3iPH9qj9Nlnn8lisWjlypXq27evwsPDNXDgQJ/gJ0kPPPCAWrRooaioKF155ZX661//ql69etXq9yVJDodDN954o1q0aCG73a7TTjtN69ev9x4/ePCgpkyZooSEBIWFhalDhw56+eWXJZml+K+//nolJyfLbrerdevWmjNnTq3bAnquGr3solL9+ke+dh0s9ndTAABAE1fsLFfXez/xy2f//LdRCg+tn3+a3nHHHXr88cf18ssvy2azqaSkRCeffLLuuOMORUdH68MPP9Sll16qtm3bqn///oe9zuOPP677779fd955p959911de+21GjJkiDp37nzY99x11116/PHHlZCQoGuuuUZXXHGFvvzyS0nSG2+8oQcffFDPPfecBg0apLfeekuPP/642rRpU+vv+pe//EWLFi3SK6+8ovT0dD3yyCMaNWqUNm/erPj4eN1zzz36+eef9fHHH6t58+bavHmziovNf1c+/fTTev/99/X2228rLS1NO3fu1M6dO2vdFhCuGr1ou9mNnV9S5ueWAAAABIabb75Z5513ns++2267zfv8hhtu0NKlS/XOO+8cMVyNHTtW1113nSQzsD355JP67LPPjhiuHnzwQQ0dOlSS9Ne//lVnnXWWSkpKZLfb9Y9//EPTp0/X5ZdfLkm69957tWzZMhUUFNTqexYWFmrevHlasGCBxowZI0n617/+peXLl+ull17S7bffrh07dqh3797q27evJLNHzmPHjh3q0KGDTjvtNFksFqWnp9eqHahAuGrkouzmryivxOnnlgAAgKYuLCRIP/9tlN8+u754goRHeXm5/v73v2vhwoXavXu3HA6HHA6HIiIijnidHj16eJ97hh/u3bu3xu9JTk6WJO3du1dpaWn69ddfvWHNo1+/flq1alWNvtehfv/9dzmdTg0aNMi7LyQkRP369dPGjRslSddee60mTpyob7/9VmeeeaYmTJiggQMHSpKmTZumM844Q506ddLo0aN19tln68wzz6xVW2AiXDVynnCVT7gCAADHmcViqbehef50aGh6/PHH9eSTT2ru3Lk66aSTFBERoZtvvlmlpaVHvM6hhTAsFotcLleN32OxWCTJ5z2efR41nWtWHc97q7umZ9+YMWO0fft2ffjhh1qxYoVGjBihGTNm6LHHHlOfPn20detWffzxx1qxYoUmTZqkkSNH6t133611m050fi1osWbNGo0bN04pKSmyWCxasmTJUd/zxhtvqGfPngoPD1dycrIuv/xyHThwwOecRYsWqWvXrrLZbOratasWL158nL7B8RcdxrBAAACAuvj88881fvx4XXLJJerZs6fatm2rTZs2NXg7OnXqpK+//tpn34YNG2p9vfbt2ys0NFRffPGFd5/T6dSGDRvUpUsX776EhARNmzZNr7/+uubOnetTmCM6OlqTJ0/Wv/71Ly1cuFCLFi1SdnZ2rdt0ovPr/5ooLCxUz549dfnll2vixIlHPf+LL77QZZddpieffFLjxo3T7t27dc011+jKK6/0Bqh169Zp8uTJuv/++3Xuuedq8eLFmjRpkr744osjjqltrKIZFggAAFAn7du316JFi7R27VrFxcXpiSeeUFZWlk8AaQg33HCDrrrqKvXt21cDBw7UwoUL9cMPP6ht27ZHfe+hVQclqWvXrrr22mt1++23Kz4+XmlpaXrkkUdUVFSk6dOnSzLndZ188snq1q2bHA6HPvjgA+/3fvLJJ5WcnKxevXrJarXqnXfeUVJSkmJjY+v1e59I/BquxowZ4518VxNfffWVWrdurRtvvFGS1KZNG/3pT3/SI4884j1n7ty5OuOMMzRz5kxJ0syZM7V69WrNnTu3SsnNQBBFQQsAAIA6ueeee7R161aNGjVK4eHhuvrqqzVhwgTl5uY2aDumTJmiLVu26LbbblNJSYkmTZqkadOmVenNqs6FF15YZd/WrVv197//XS6XS5deeqny8/PVt29fffLJJ4qLi5MkhYaGaubMmdq2bZvCwsI0ePBgvfXWW5KkyMhIPfzww9q0aZOCgoJ0yimn6KOPPpLVympNtWUx6jLQsx5ZLBYtXrxYEyZMOOw5a9eu1fDhw7V48WKNGTNGe/fu1aRJk9SlSxc9//zzkqS0tDT9+c9/1p///Gfv+zxjbLdv317tdT2TGj3y8vKUmpqq3NxcRUdH188XrKWs3BKdOmelgqwWbX5wTJUxtQAAALVVUlKirVu3qk2bNrLb7f5uzgnpjDPOUFJSkl577TV/N+WEdqQ/C3l5eYqJialRNgioWDpw4EC98cYbmjx5skJDQ73dlv/4xz+852RlZSkxMdHnfYmJicrKyjrsdefMmaOYmBjvlpqaety+w7HyFLQodxkqdpb7uTUAAACoraKiIj3xxBP66aef9Msvv2jWrFlasWKFpk6d6u+moZ4EVLj6+eefdeONN+ree+/VN998o6VLl2rr1q265pprfM47UsWU6sycOVO5ubnerTEtnhYeGqQgq9n2vGKGBgIAAAQqi8Wijz76SIMHD9bJJ5+s//u//9OiRYs0cuRIfzcN9SSgam3OmTNHgwYN0u233y7JXEcgIiJCgwcP1gMPPKDk5GQlJSVV6aXau3dvld6symw2m2w223Fte21ZLBZF2YOVU+RUfolTSTF02QMAAASisLAwrVixwt/NwHEUUD1XRUVFVSbYBQWZC855po4NGDBAy5cv9zln2bJl3sXSAlHFQsL0XAEAAACNlV97rgoKCrR582bv661btyojI8NbSnLmzJnavXu3Xn31VUnSuHHjdNVVV2nevHkaNWqUMjMzdfPNN6tfv35KSUmRJN10000aMmSIHn74YY0fP17/+c9/tGLFCp/6/4EmyhYiqZhy7AAAAEAj5tdwtWHDBg0fPtz7+pZbbpEkTZ06VQsWLFBmZqZ27NjhPT5t2jTl5+frmWee0a233qrY2Fidfvrpevjhh73nDBw4UG+99Zbuvvtu3XPPPWrXrp0WLlwYkGtceXh6rijHDgAAADRejaYUe2NyLOUWG8JVr27Q8p//0IPndteU/un+bg4AAGgiKMUOmE7IUuwnKu+cK6oFAgAAAI0W4SoARNtDJEn5zLkCAAAAGi3CVQCIZs4VAADACWnYsGG6+eabva9bt26tuXPnHvE9FotFS5YsqfNn19d1TiSEqwAQ5e65ologAACAKSsrSzfccIPatm0rm82m1NRUjRs3TitXrvR30ySZVa4PtzjwunXrZLFY9O233x7zddevX6+rr766rs3zMXv2bPXq1avK/szMTI0ZM6ZeP+tQCxYsUGxs7HH9jIYUUIsIn6ioFggAAFBh27ZtGjRokGJjY/XII4+oR48ecjqd+uSTTzRjxgz98ssv1b7P6XQqJCSkQdo4ffp0nXfeedq+fbvS030Lks2fP1+9evVSnz59jvm6CQkJ9dXEo0pKSmqwz2oq6LkKANFhzLkCAAANwDCk0kL/bMdQwPq6666TxWLR119/rfPPP18dO3ZUt27ddMstt+irr77ynmexWPT8889r/PjxioiI0AMPPCBJmjdvntq1a6fQ0FB16tRJr732ms/1Z8+erbS0NNlsNqWkpOjGG2/0HnvuuefUoUMH2e12JSYm6vzzz6+2jWeffbZatGihBQsW+OwvKirSwoULNX36dB04cEAXXXSRWrVqpfDwcJ100kl68803j/jdDx0WuGnTJg0ZMkR2u11du3bV8uXLq7znjjvuUMeOHRUeHq62bdvqnnvukdNp/rtywYIFuu+++/T999/LYrHIYrF423zosMAff/xRp59+usLCwtSsWTNdffXVKigo8B6fNm2aJkyYoMcee0zJyclq1qyZZsyY4f2s2tixY4fGjx+vyMhIRUdHa9KkSfrjjz+8x7///nsNHz5cUVFRio6O1sknn6wNGzZIkrZv365x48YpLi5OERER6tatmz766KNat6Um6LkKAPRcAQCABuEskh5K8c9n37lHCo046mnZ2dlaunSpHnzwQUVEVD3/0CFms2bN0pw5c/Tkk08qKChIixcv1k033aS5c+dq5MiR+uCDD3T55ZerVatWGj58uN599109+eSTeuutt9StWzdlZWXp+++/l2Su0XrjjTfqtdde08CBA5Wdna3PP/+82nYGBwfrsssu04IFC3TvvffKYrFIkt555x2VlpZqypQpKioq0sknn6w77rhD0dHR+vDDD3XppZeqbdu2NVqj1eVy6bzzzlPz5s311VdfKS8vz2d+lkdUVJQWLFiglJQU/fjjj7rqqqsUFRWlv/zlL5o8ebL+97//aenSpVqxYoUkKSYmpso1ioqKNHr0aJ166qlav3699u7dqyuvvFLXX3+9T4D89NNPlZycrE8//VSbN2/W5MmT1atXL1111VVH/T6HMgxDEyZMUEREhFavXq2ysjJdd911mjx5sj777DNJ0pQpU9S7d2/NmzdPQUFBysjI8PZOzpgxQ6WlpVqzZo0iIiL0888/KzIy8pjbcSwIVwHAO+eqmJ4rAABwYtu8ebMMw1Dnzp1rdP7FF1+sK664wuf1tGnTdN1110mSt7frscce0/Dhw7Vjxw4lJSVp5MiRCgkJUVpamvr16yfJ7EWJiIjQ2WefraioKKWnp6t3796H/ewrrrhCjz76qD777DMNHz5ckjkk8LzzzlNcXJzi4uJ02223ec+/4YYbtHTpUr3zzjs1ClcrVqzQxo0btW3bNrVq1UqS9NBDD1WZJ3X33Xd7n7du3Vq33nqrFi5cqL/85S8KCwtTZGSkgoODjzgM8I033lBxcbFeffVVb6h95plnNG7cOD388MNKTEyUJMXFxemZZ55RUFCQOnfurLPOOksrV66sVbhasWKFfvjhB23dulWpqamSpNdee03dunXT+vXrdcopp2jHjh26/fbbvfdDhw4dvO/fsWOHJk6cqJNOOkmS1LZt22Nuw7EiXAUAqgUCAIAGERJu9iD567NrwHAPH/T0BB1N3759fV5v3LixSkGIQYMG6amnnpIkXXDBBZo7d67atm2r0aNHa+zYsRo3bpyCg4N1xhlnKD093Xts9OjROvfccxUeHq433nhDf/rTn7zX/PjjjzV48GANHDhQ8+fP1/Dhw/X777/r888/17JlyyRJ5eXl+vvf/66FCxdq9+7dcjgccjgc1fbIVWfjxo1KS0vzBitJGjBgQJXz3n33Xc2dO1ebN29WQUGBysrKjroYbnWf1bNnT5+2DRo0SC6XS7/++qs3XHXr1k1BQUHec5KTk/Xjjz8e02dV/szU1FRvsJKkrl27KjY2Vhs3btQpp5yiW265RVdeeaVee+01jRw5UhdccIHatWsnSbrxxht17bXXatmyZRo5cqQmTpyoHj161KotNcWcqwDg6bkqKC2Ty1Xz8cgAAADHxGIxh+b5Y6thWOrQoYMsFos2btxYo/OrCyqHBjPDMLz7UlNT9euvv+rZZ59VWFiYrrvuOg0ZMkROp1NRUVH69ttv9eabbyo5OVn33nuvevbsqZycHJ1zzjnKyMjwbp5QN336dC1atEh5eXl6+eWXlZ6erhEjRkiSHn/8cT355JP6y1/+olWrVikjI0OjRo1SaWlpjb6bUc08tUO/21dffaULL7xQY8aM0QcffKDvvvtOd911V40/o7qf0ZE+89CCIRaLRS6X65g+62ifWXn/7Nmz9dNPP+mss87SqlWr1LVrVy1evFiSdOWVV2rLli269NJL9eOPP6pv3776xz/+Uau21BThKgB45lwZhpTvoPcKAACcuOLj4zVq1Cg9++yzKiwsrHI8JyfniO/v0qWLvvjiC599a9euVZcuXbyvw8LCdM455+jpp5/WZ599pnXr1nl7X4KDgzVy5Eg98sgj+uGHH7Rt2zatWrVKUVFRat++vXcLCwuTJE2aNElBQUH697//rVdeeUWXX365Nxh8/vnnGj9+vC655BL17NlTbdu21aZNm2r8s+jatat27NihPXsqehvXrVvnc86XX36p9PR03XXXXerbt686dOig7du3+5wTGhqq8vLyo35WRkaGz8/8yy+/lNVqVceOHWvc5mPh+X47d+707vv555+Vm5vr8/vq2LGj/vznP2vZsmU677zz9PLLL3uPpaam6pprrtF7772nW2+9Vf/617+OS1s9GBYYAOwhQQoNtqq0zKX8EqdiwhqmhCgAAEBj9Nxzz2ngwIHq16+f/va3v6lHjx4qKyvT8uXLNW/evCP2at1+++2aNGmS+vTpoxEjRuj//u//9N5773mLOSxYsEDl5eXq37+/wsPD9dprryksLEzp6en64IMPtGXLFg0ZMkRxcXH66KOP5HK51KlTp8N+XmRkpCZPnqw777xTubm5mjZtmvdY+/bttWjRIq1du1ZxcXF64oknlJWV5RMcjmTkyJHq1KmTLrvsMj3++OPKy8vTXXfd5XNO+/bttWPHDr311ls65ZRT9OGHH3p7djxat26trVu3KiMjQ61atVJUVJRsNpvPOVOmTNGsWbM0depUzZ49W/v27dMNN9ygSy+91DsksLbKy8uVkZHhsy80NFQjR45Ujx49NGXKFM2dO9db0GLo0KHq27eviouLdfvtt+v8889XmzZttGvXLq1fv14TJ06UJN18880aM2aMOnbsqIMHD2rVqlU1/tnWFj1XAYJ5VwAAAKY2bdro22+/1fDhw3Xrrbeqe/fuOuOMM7Ry5UrNmzfviO+dMGGCnnrqKT366KPq1q2b/vnPf+rll1/WsGHDJJnVBv/1r39p0KBB6tGjh1auXKn/+7//U7NmzRQbG6v33ntPp59+urp06aLnn39eb775prp163bEz5w+fboOHjyokSNHKi0tzbv/nnvuUZ8+fTRq1CgNGzZMSUlJmjBhQo1/DlarVYsXL5bD4VC/fv105ZVX6sEHH/Q5Z/z48frzn/+s66+/Xr169dLatWt1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5lwBAAAA/ke4agKiw5hzBQAAAPgb4aoJoOcKAAAA8D/CVRPgqRbInCsAAADAfwhXTUA01QIBAAAAvyNcNQGeYYHFznI5y11+bg0AAABwYiJcNQGR7nAlSQXMuwIAAAD8gnDVBIQEWRUeGiSJioEAAACAvxCumggqBgIAAAD+RbhqIqLsrHUFAAAA+BPhqomIpucKAAAA8KtahaudO3dq165d3tdff/21br75Zr3wwgv11jAcG2/PVTE9VwAAAIA/1CpcXXzxxfr0008lSVlZWTrjjDP09ddf684779Tf/va3em0gaoY5VwAAAIB/1Spc/e9//1O/fv0kSW+//ba6d++utWvX6t///rcWLFhQn+1DDUWHmT1XhCsAAADAP2oVrpxOp2w2myRpxYoVOueccyRJnTt3VmZmZv21DjXm6bmioAUAAADgH7UKV926ddPzzz+vzz//XMuXL9fo0aMlSXv27FGzZs3qtYGomWi7p+eKcAUAAAD4Q63C1cMPP6x//vOfGjZsmC666CL17NlTkvT+++97hwvWxJo1azRu3DilpKTIYrFoyZIlRzx/2rRpslgsVbZu3br5nLdo0SJ17dpVNptNXbt21eLFi4/5OwYa5lwBAAAA/lWrcDVs2DDt379f+/fv1/z58737r776aj3//PM1vk5hYaF69uypZ555pkbnP/XUU8rMzPRuO3fuVHx8vC644ALvOevWrdPkyZN16aWX6vvvv9ell16qSZMm6b///W/Nv2AAimadKwAAAMCvgmvzpuLiYhmGobi4OEnS9u3btXjxYnXp0kWjRo2q8XXGjBmjMWPG1Pj8mJgYxcTEeF8vWbJEBw8e1OWXX+7dN3fuXJ1xxhmaOXOmJGnmzJlavXq15s6dqzfffLPGnxVo6LkCAAAA/KtWPVfjx4/Xq6++KknKyclR//799fjjj2vChAmaN29evTbwSF566SWNHDlS6enp3n3r1q3TmWee6XPeqFGjtHbt2sNex+FwKC8vz2cLNFF2qgUCAAAA/lSrcPXtt99q8ODBkqR3331XiYmJ2r59u1599VU9/fTT9drAw8nMzNTHH3+sK6+80md/VlaWEhMTffYlJiYqKyvrsNeaM2eOt1csJiZGqampx6XNx1N0mLtaIIsIAwAAAH5Rq3BVVFSkqKgoSdKyZct03nnnyWq16tRTT9X27dvrtYGHs2DBAsXGxmrChAlVjlksFp/XhmFU2VfZzJkzlZub69127txZ38097ui5AgAAAPyrVuGqffv2WrJkiXbu3KlPPvnEOwxv7969io6OrtcGVscwDM2fP1+XXnqpQkNDfY4lJSVV6aXau3dvld6symw2m6Kjo322QOOZc1Va7lKJs9zPrQEAAABOPLUKV/fee69uu+02tW7dWv369dOAAQMkmb1YvXv3rtcGVmf16tXavHmzpk+fXuXYgAEDtHz5cp99y5Yt08CBA497u/wpMjRYns45KgYCAAAADa9W1QLPP/98nXbaacrMzPSucSVJI0aM0Lnnnlvj6xQUFGjz5s3e11u3blVGRobi4+OVlpammTNnavfu3d7iGR4vvfSS+vfvr+7du1e55k033aQhQ4bo4Ycf1vjx4/Wf//xHK1as0BdffFGLbxo4rFaLIm3Byi8pU35JmVpE+btFAAAAwImlVuFKMoffJSUladeuXbJYLGrZsuUxLSAsSRs2bNDw4cO9r2+55RZJ0tSpU7VgwQJlZmZqx44dPu/Jzc3VokWL9NRTT1V7zYEDB+qtt97S3XffrXvuuUft2rXTwoUL1b9//2P8hoEn2h7iDVcAAAAAGpbFMAzjWN/kcrn0wAMP6PHHH1dBQYEkKSoqSrfeeqvuuusuWa21Gm3YaOTl5SkmJka5ubkBNf9q9Nw1+iUrX69N76fBHRL83RwAAAAg4B1LNqhVz9Vdd92ll156SX//+981aNAgGYahL7/8UrNnz1ZJSYkefPDBWjUcdRPtrhiYV0zPFQAAANDQahWuXnnlFb344os655xzvPt69uypli1b6rrrriNc+YmnYmA+BS0AAACABler8XvZ2dnq3Llzlf2dO3dWdnZ2nRuF2okOY60rAAAAwF9qFa569uypZ555psr+Z555Rj169Khzo1A7np4rSrEDAAAADa9WwwIfeeQRnXXWWVqxYoUGDBggi8WitWvXaufOnfroo4/qu42ooYphgfRcAQAAAA2tVj1XQ4cO1W+//aZzzz1XOTk5ys7O1nnnnaeffvpJL7/8cn23ETXkLWhBzxUAAADQ4Gq9zlVKSkqVwhXff/+9XnnlFc2fP7/ODcOxi6JaIAAAAOA3gb0gFXxQLRAAAADwH8JVE8KcKwAAAMB/CFdNiKcUO3OuAAAAgIZ3THOuzjvvvCMez8nJqUtbUEfR9FwBAAAAfnNM4SomJuaoxy+77LI6NQi15yloUeAok2EYslgsfm4RAAAAcOI4pnBFmfXGzVOKvdxlqKi0XBG2WheDBAAAAHCMmHPVhNhDrAq2mr1VzLsCAAAAGhbhqgmxWCxUDAQAAAD8hHDVxHgqBrLWFQAAANCwCFdNjKfnKq+YnisAAACgIRGumpgoG2tdAQAAAP5AuGpiosOYcwUAAAD4A+GqifGsdUXPFQAAANCwCFdNDNUCAQAAAP8gXDUxnoWEqRYIAAAANCzCVRNDtUAAAADAPwhXTQw9VwAAAIB/EK6aGKoFAgAAAP5BuGpiqBYIAAAA+AfhqomhWiAAAADgH4SrJibKO+eKcAUAAAA0JMJVExPt7rkqcJSp3GX4uTUAAADAiYNw1cR4eq4kqYDeKwAAAKDBEK6amNBgq2zB5q+VohYAAABAwyFcBQJnseRy1fj06DDmXQEAAAANjXDV2K1/UZrbQ/r1wxq/xVMxkJ4rAAAAoOEQrhq7vD1S4V5pzWOSUbMCFVQMBAAAABoe4aqxO/U6KSRcysyQNq+s0VuivWtd0XMFAAAANBTCVWMX0Vw6+XLz+ZpHa9R7Fe3uucorJlwBAAAADYVwFQgG3iAFhUo7v5K2f3nU06O8PVcMCwQAAAAaCuEqEEQnS70vMZ+vefTop3uqBToIVwAAAEBDIVwFikE3S5Ygactn0q4NRzw1yuauFsiwQAAAAKDBEK4CRVy61GOy+XzNY0c8lWGBAAAAQMMjXAWSwbdIski/fSxl/XjY0zzDAlnnCgAAAGg4hKtA0ryD1O1c8/nnjx/2NNa5AgAAABoe4SrQDL7VfPxpibR/U7WneIYF0nMFAAAANBzCVaBJ6i51GivJkD5/otpTmHMFAAAANDzCVSAafJv5+MNC6eD2KoejvcMC6bkCAAAAGgrhKhC1OllqO1wyyqUv51Y57AlXJU6XSstcDdw4AAAA4MREuApUQ243H797Xcrb43Mo0j0sUKL3CgAAAGgohKtA1XqQlDZAKi+V1j7jcyjIalGkjXlXAAAAQEMiXAWyIe65VxvmS4X7fQ5RMRAAAABoWISrQNZuhJTcSyorlr56zucQFQMBAACAhkW4CmQWS8Xcq6//JRXneA9RMRAAAABoWISrQNdprNSiq+TIMwOWm3dYYDE9VwAAAEBDIFwFOqtVGnyr+fyrZyVHgSQpyt1zxZwrAAAAoGEQrpqCbudK8e2k4oNmcQtJ0WHMuQIAAAAaEuGqKbAGSaf92Xy+7hnJWUzPFQAAANDACFdNRY/JUkyqVPCH9N3rVAsEAAAAGhjhqqkIDpUG3WQ+//IpxYaaT6kWCAAAADQMwlVT0vsSKTJRyt2pLvs+kkTPFQAAANBQCFdNSUiYNPAGSVKnTS/KKhdzrgAAAIAGQrhqak6+XAqLU3jBdp1t/YqeKwAAAKCBEK6aGlukdOoMSdJ1wf9RVm6RsnJL/NwoAAAAoOkjXDVF/a6SYYtWZ+tODXWt1wMf/uzvFgEAAABNHuGqKQqLlaXfVZKkO4Lf0n9/+Fmfb9rn50YBAAAATRvhqqk6dYYUkaB21kwtsd2rl9/7UI6ycn+3CgAAAGiyCFdNVUQzafoylce3V0vLAT1V9Fd9vOQNf7cKAAAAaLIIV01ZfFsFXblc+5ufoihLsc7+8SYdWP1Pf7cKAAAAaJIIV01deLyaXfOhPg8fqWCLS80+/YuMZfdILpe/WwYAAAA0KYSrE4Al2KaW0xbo6fLzzddrn5bemSo5i/3cMgAAAKDpIFydINq2iJJz8F90c+l1cipY2vi+tOBsqYAqggAAAEB9IFydQGYMb69vYs/QFMdMFQdFS7s3SC+eLu371d9NAwAAAAIe4eoEYg8J0n3ndNPXRhedUzxLpdHpUs4O6cUzpC2r/d08AAAAIKARrk4wp3dO1KhuidrkSta19kdkpPaXHLnS6+dJ31GqHQAAAKgtv4arNWvWaNy4cUpJSZHFYtGSJUuO+h6Hw6G77rpL6enpstlsateunebPn+89vmDBAlkslipbSUnJcfwmgeXecd0UFhKklTvKtfikeVK38yRXmfSf66RVD0iG4e8mAgAAAAHHr+GqsLBQPXv21DPPPFPj90yaNEkrV67USy+9pF9//VVvvvmmOnfu7HNOdHS0MjMzfTa73V7fzQ9YLWPDdNPIDpKkBz/Zopyx86TBt5oH1zwqLbpSchJGAQAAgGMR7M8PHzNmjMaMGVPj85cuXarVq1dry5Ytio+PlyS1bt26ynkWi0VJSUn11cwm6YpBbbTom13atLdAjy7bpAfPvVeKayN9cLP0v3elvN3SBa9IUYn+bioAAAAQEAJqztX777+vvn376pFHHlHLli3VsWNH3XbbbSou9l2vqaCgQOnp6WrVqpXOPvtsfffdd0e8rsPhUF5ens/W1IUGW3X/hO6SpH9/vUMZO3OkPpdKU96VbNHSjnXS84Ok31f5t6EAAABAgAiocLVlyxZ98cUX+t///qfFixdr7ty5evfddzVjxgzvOZ07d9aCBQv0/vvv680335TdbtegQYO0adOmw153zpw5iomJ8W6pqakN8XX87tS2zXRe75YyDOnuJT+q3GVI7YZLV66UWnSVCvdJr50nrbhPKnf6u7kAAABAo2YxjMZRvcBisWjx4sWaMGHCYc8588wz9fnnnysrK0sxMTGSpPfee0/nn3++CgsLFRYWVuU9LpdLffr00ZAhQ/T0009Xe12HwyGHw+F9nZeXp9TUVOXm5io6OrpuX6yR25fv0IjHP1NeSZnuO6ebpg5sbR5wFktLZ0rfvGy+Tu0vTXxRik3zW1sBAACAhpaXl6eYmJgaZYOA6rlKTk5Wy5YtvcFKkrp06SLDMLRr165q32O1WnXKKaccsefKZrMpOjraZztRJETZdPtosyDIY5/8qr357kIWIWHSuLnSBQvMYYI7/ys9f5q08QO/tRUAAABozAIqXA0aNEh79uxRQUGBd99vv/0mq9WqVq1aVfsewzCUkZGh5OTkhmpmwLm4X5p6tIpRvqNMD3240fdgt3OlP62RUvpIJbnSwinSR3+RyhzVXwwAAAA4Qfk1XBUUFCgjI0MZGRmSpK1btyojI0M7duyQJM2cOVOXXXaZ9/yLL75YzZo10+WXX66ff/5Za9as0e23364rrrjCOyTwvvvu0yeffKItW7YoIyND06dPV0ZGhq655poG/36BIshq0QMTustikZZk7NHazft9T4hvI13xiTTgevP11/+UXhwp7d/c8I0FAAAAGim/hqsNGzaod+/e6t27tyTplltuUe/evXXvvfdKkjIzM71BS5IiIyO1fPly5eTkqG/fvpoyZYrGjRvnM5cqJydHV199tbp06aIzzzxTu3fv1po1a9SvX7+G/XIBpkerWF3SP12SdPd//qfSMpfvCcGh0qgHpYvflsLipawfpBeGSj+87YfWAgAAAI1Poylo0Zgcy6S1piS32KkRj3+m/QWlun1UJ80Y3r76E/P2mAsNb//SfN3rEmnsI1JoRMM1FgAAAGgATbagBY6vmLAQ3XVWF0nSP1Zt0g+7cqo/MTpFmvp/0tC/SrJIGa9LLwyX/vipwdoKAAAANDaEK/iY0KulBrVvphKnS5P/+ZWW/ZRV/YnWIGn4TDNkRSZJ+3+V/nW6tGG+RGcoAAAATkCEK/iwWCx6/pKTNbRjgoqd5frT699o/hdbD/+GNoOla7+U2p8hlZVIH/xZenGE9N0bUmlRwzUcAAAA8DPmXFXjRJ1zVVlZuUv3vv+T/v1fs6DItIGtdc/ZXRVktVT/BpdLWveMtOp+qbzU3GePkXpeJJ18udSicwO1HAAAAKg/x5INCFfVIFyZDMPQC2u2aM7Hv0iSRnZpoacu7K0IW/Dh31SwV/rudembl6WcikqPShso9b1c6nKOFGI/zi0HAAAA6gfhqo4IV74++jFTf16YIUeZS91bRmv+1FPUIvooAcnlkraskja8LP36sWSUm/vD4qVeF5u9Wc0PU40QAAAAaCQIV3VEuKrqm+0HdfWrG3SgsFQpMXbNv/wUdU6q4c8mb4/07WvSt69Iebsr9rcZYoaszmeb62gBAAAAjQzhqo4IV9XbcaBI0xZ8rS37ChVpC9ZzU/poSMeEml+gvEzavNzszdq0TJL71otIkHpfIvW+VGrW7ri0HQAAAKgNwlUdEa4OL6eoVH967Rv9d2u2gqwWPTihuy7sl1aLC+2Qvn3V3Ar+qNjfoqvU+Syp01gppbdkOUwBDQAAAKABEK7qiHB1ZI6ycs1c9KPe+84c4nftsHa6/cxOsh6ukuCRlDvNOVnfLJC2fFYxN0uSoluaIavzWCn9NIYOAgAAoMERruqIcHV0hmHoqZWbNHfFJknSWT2S9fgFPWUPCar9RYuyzeGCv3wobV4pOQsrjtlipA5nmL1a7UdKdn4vAAAAOP4IV3VEuKq5Rd/s0l/f+0HOckMnp8fphUtPVrNIW90v7CyRtq6WfvnA7Nkq3FdxLCjULIbhGT4YlVT3zwMAAACqQbiqI8LVsVn3+wH96bUNyispU3qzcL1waV91Soqqvw9wlUu7Nki/fmj2ah3Y7Hu85clSh1FSh5FScm/Jaq2/zwYAAMAJjXBVR4SrY7d5b74uX7BeO7OLFWS16NJT0/XnkR0VEx5S/x+27zezR+uXD6XdG3yPhTc3hw12OENqd7oUHl//nw8AAIATBuGqjghXtbO/wKG7Fv+oT34yq//FR4Tq1jM76sJT0hRUm2IXNZGfJf32iVni/ffPpNL8imMWq9mr1f4MerUAAABQK4SrOiJc1c0Xm/brbx/8pN/+KJAkdU2O1uxzuqlfm+Pci1RWKu38rxm0Nq2Q9v7ke5xeLQAAABwjwlUdEa7qrqzcpde/2q4nlv+mvJIySdLZPZJ159guSokNa5hG5O52B63l0pbV1fdqpfaXEjpLLbpICZ0kWz3OFQMAAEDAI1zVEeGq/mQXlurxZb/q31/vkGFI9hCrrh3aXn8a2rZuZduPlU+v1nJp78/VnxeT6g5bnaWELu7HzlJoRMO1FQAAAI0G4aqOCFf176c9ubrv/Z/19bZsSVLL2DDddVYXjemeJIvlOM3HOpLcXdLvn0p//E/au1Ha94tU8Mfhz49Nc4ct95bYXWrRlTlcAAAATRzhqo4IV8eHYRj64IdMzfloo/bklkiSTm0br1njuqlLciP4ORdlmyHLE7Y8j5XX2KosvJnUerC55laboVKzdpI/giIAAACOG8JVHRGujq/i0nLNW/27/rn6dznKXLJapCn903XLGR0VFxHq7+ZVVXhA2rexUuj6RdrzneQs9D0vuqU7aLnDVkxL/7QXAAAA9YZwVUeEq4ax62CRHvpooz76MUuSFGkL1kX9UnX5oDYNV/Sitsqd0u5vpa2rpa1rzPlc5aW+58S3k9oONcNW68FSRHP/tBUAAAC1RriqI8JVw1r7+37d/8FGbczMkyQFWy06u0eyrhzcVt1bxvi5dTXkLJZ2fGUGra1rpD3fSobL95zEk8yglXaquUW28E9bAQAAUGOEqzoiXDU8l8vQ6k379K81W7T29wPe/YPaN9NVg9tqaMcE/xS+qK2SXGn7WrME/NY1VdfckqS4NmbISu1vPjbvRIEMAACARoZwVUeEK//63+5c/evzLfrgh0yVu8zbs1NilK4c3Ebn9EqRLbgBS7jXl4J90rY10tbPzSGEezdKOuSPnj1WSu1XEbZS+kih4f5oLQAAANwIV3VEuGocducU6+UvturNr3eosLRcktQiyqZpg1prSr90xYSH+LmFdVCcI+3aIO38yhxOuPsbyVnke441WEruKaWeKqW5FzsOi5fC4qSgYL80GwAA4ERDuKojwlXjklvs1Ftf79DLX25TVp5Zwj08NEiTT0nVFYPaKDW+CfTulDulrB/NXq0dX5mP+ZmHP98WI4XHm1tYvFkW3vs83vd5VDLFNAAAAGqJcFVHhKvGqbTMpQ9+2KMX1mzRL1n5kiSrRRpzUrKm9E/TqW2ayWoNoHlZR2IYUs6OSmHrayl3p1SSU7vrxaa7hxv2N3vCWnSRrAE4vBIAAKCBEa7qiHDVuBmGoS8279cLa7bo8037vftT48N0wcmpmnhyK7Vs7KXca8tVbg4pLDogFWebCx9Xfu7d53l+QCrcryrzu2zRUqu+ZtBK7Wc+t0X54xsBAAA0aoSrOiJcBY6f9+Tp9f9u1/9l7FG+o0ySZLFIp7Vvrkl9U3VG10TZQ07wHpqSPGn3BmnHf82esF0bpNJ833MsVimxe0X1wtT+Umyqf9oLAADQiBCu6ohwFXiKS8u19KdMvb1+l9ZtqSjlHhMWogm9UnRB39TAWTPreHOVS3/8ZAatnf81Q1fujqrnRbeUEjqZQwrj0qW41u7nrc2iGoFUGh8AAKCWCFd1RLgKbDsOFOndb3bqnW92KTO3xLu/a3K0JvVtpfG9WiouItSPLWyE8vZUBK2d/5WyfpBcZYc/PzTKDFlx6VXDV2waJeQBAECTQbiqI8JV01DuMvTl5v16e8NOLfvpD5WWuyRJoUFWndEtUZP6puq09s0V1FSKYNSn0kIp83spe4t0cLt0cJuUs918XpB19PfHpEopvaSU3uZ6XSm9zN4uAACAAEO4qiPCVdOTU1Sq/2Ts0dsbduqnPXne/TFhITqtfXMN6dhcgzskKKWpFsKoT85is5Lhwe3uwLWtUvjaITlyq39ffNtKYau3uYaXLbLu7SkvM6so2qKkYFvdrwcAAFAJ4aqOCFdN2/925+rdb3ZpScZu5RQ5fY61bxGpwR2aa0jHBPVvE6/wUBbrPWZF2dLen6U930m7vzUfD26tep7FKjXvZAatlu7A1aKLVFpkVjn0bJ6qh0WVqiNW3l/iDnOWIHNoYkInqXlH92MnqXkHyc6fYwAAUDuEqzoiXJ0Yyspd+n5Xrtb8tk+fb9qnjJ05clX60xAaZNUpbeI0uEOChnRIUJfkKFko4lA7RdlmyKq85e1uuM+PSpESOpphy/vYSYpIoDAHAAA4IsJVHRGuTky5RU59+ft+fb5pn9b8tl+7c4p9jjePtGlIh+Ya7B5C2DySIWh1kp9VEbR2fyvt+dbsiZLM+Vlh8VJ4s0pbXMVzn2Pxkj1WKtwn7f9V2veb+/FXaf9vUsEfh2+DPdbs2fIU4vBu6VJMKynE3hA/CQAA0IgRruqIcAXDMLRlf6G7V2u/1v1+QMXOcp9zuqVEa2jHBA3pmKA+aXEKDbb6qbVNhGGYQ/xCI6WgehyOWXxQ2r/JHbYqha+D21VlceVDRSaZ6335BK/K4auRztFz5Et7N0p//E/642dp3y/mMEx7tLmAtC3a/TzK/TrK/Tqm0vMo83dBzx4A4ARHuKojwhUO5Sgr1zfbD2rNb/u15rd9+jkzz+d4RGiQBrY352oN7ZCgtGaUIm/0nMXSgc3Sgd+l3J1mkQ7PdnC75Cw8+jVi0sxhhgmd3fO8OpuvG6oyoqvcrOj4x//Mtcv++Nl8nrO9fq5vsZrfa+CNUo/J9Rt6AQAIEISrOiJc4Wj25Tvcwwf3ac2m/couLPU53qZ5hIZ0aK6hnRJ0attmFMYINIZh9njlbPcNXZW30oLDvz8ysaKoRuXgFdmiZj1BLpdUVmJuzmJzKyuWCvebxUI8IWrfL+Y51YlKllp0lRK7mYVCLEGSI8+95Usl7kef1+6tJE8yfHtqFddaGnyb1PNCKSikxj9KAAACHeGqjghXOBYul6Gf9uRpzaZ9Wv3bPn27/aDKKlXGCA2yqm/rOA3paBbG6JwUJStrawU2wzDnh+3/rWJu175fzCGHebsO/z57jFlMIyy2IjR5gpOzRHIWVYSqmgoJN8NTYjepRTfzMbGbORetLt/PWWyWuP/hbWnt0xXz4WLTpcG3Sr0uJmQBAE4IhKs6IlyhLvJLnFr7+wGt+c0MW7sO+hbGiLYHq1danE5Oi1Of9Fj1So1VlJ1/pDYZjnx32HIHLk8AO7hVMlzHfj1riBmgQuzm/KgWnaXE7hW9UnFtJOtxnu9XWiitf8kMWYX7zH0xadLgW6ReU6Tg0OP7+QAA+BHhqo4IV6gvhmFoq7swxppN+/XVlgMqKvUdbmWxSB1bRKlPeqx6p8Xp5PQ4tW0eQdn3psZZImX/bgYuZ7EUbK8ITSHh7tdh5hYcVvHcGuTvllcoLZI2zJe+fEoq3Gvui0mVTvuz1PsSFnEGADRJhKs6IlzheCkrd+mXrHx9u+Ogvt1+UN/sOKid2cVVzosND1Hv1Fj1SYtTn/Q49UyNVaSNeVtoJEqLpG8WSF/OrSh1H93SDFl9Ljs+Ics7D26HuwDJzkrP3fPgHHlmhcPQCPcWaW62yvuizEfvPvc5IWG+YbexhNzig2bP575fzMcDv0uRCVJyL3NL6t54q1YCQBNBuKojwhUa0t78En23I8cbuH7YlStHme/wMavFLJLRNiFS7RIi1TYhQu0SItQuIVKx4QzJgp84i6VvXjFDVn6muS8qpSJkVbdOmMsllTukMvdW7pDKSs15ZuUOs4ev4I/qQ9SRiogcb0G26oNXWKxZwCSyhVm6P7KFFJVUsc8WdfRrG4ZZrGTfLxUhyrNW25HWaZPMQiUJnaXknlJKL/Mx6SQzOAIA6gXhqo4IV/Cn0jKXNmbm6ZvtB/XtjoP6bkdOlQWNK4uPCFXb5hHe0GUGsAilxocrJIi1t9AAnCXSt69KXzwp5e8x94XFmwU8yt3ByROgXM66fVZEgjkUMTbNXIMsJq1iLbKwODPwlRZIjgJzrlhpgXsrPGR/oVSabz46CtxFRSoVFvEUGqmrkAh38EqUohLdoSvRHAZ6YHNFr1Rx9uGvEd2qovJks7ZSXqaU+b2UmVExB64yTwn95J5m71ZKLzNwVRf0DENylUnlTvN3U15mvnY53fvcw5hjWtJDBuCERbiqI8IVGps/8kr0a1a+tuwr0Jb9hfp9X4G27CtUZu7hq8oFWy1Kaxauts0jlRofplZx4WoVF6bUuHC1ig9TNEU0UN/KHBUhK293zd4TbDd7hYLdW1CoGaA8gSkm1f3cDws3e3rZnMUVgcu7FZlbcY5UkCUV7JXy3Y8Ff5jbMfW0WaS4dPdaaZ0qHpt3PHzvl2GYPYZ7MirC1p4Msz3VXT+8mTs4lVUEqkNL7h9JdCsz3MW3k5q1l5q1M5/HtT5xi5qUl5nDUe2xx6ewjGGY91L2FnNIaPYWc+6mI9/8zLA491bp+aH7Ay0UFx+UfvtE2vaF+ee+7VAppQ/r7MGvCFd1RLhCoCh0lGlrpbC1ZX+hft9boK37C1XsPPI/mqLtwUqNNwNXq7hwpbofW7mDGHO8UGtlDmnPd5Is5j+6g+1maAq2VwSoYLtZyr0pF25xFLiDVqXA5Q1ehWYw8YSoZu2l0HpafDw/S8r8wQxbmd+bgetISwRUYTF/N9Zgs1qlUX7koGixmkE4vp0ZuJq1dz9vK0W0OD5z1gzDvM8867I5cs3H0sKK4Zp2zxZT+3+YOwqk3F3msNTcnebznJ0V+/L2mD8fa7D5XaMSzeGhh3uMbFF1CQPDMO+R7N99A1T2Fil7a92HwwbbK4WtePfvqq0U38b92Nb8eflT3h7plw+lXz4wQ5WrzPe4LVpKHyS1HWaGrYTOTfvvDjQ6hKs6Ilwh0LlchrLySvT7vgJt21+oXTnF2pVdrF0Hi7TrYLEOHLLocXXiwkPUvWWMTmkdr1Nax6t3WqzsIY2och2Amivcb/4DPijEDDpWd3jyhijP85CqPTCGIRVlm8MYPQHA+3yL5Cw8+ud7q2GGV8xbC42oui8k3AyZnkWvPYtbl+Qe8jrv2IaYhka5A1eMu2cnttKje19ZSdUgVXyw5p9RU+HN3EErwVw/7mgBymI1e3Dj21b0FobFmj+T4oNm72nxQXMrqfS8OKfmPZPhzSqC1qFbWNzxCTL7N0kb/88MVLu/8T3WoqvUfoR0cJu09XPze1UWmSi1GWoGrTZDzd7tpspVbi5ov3+TubTH/t/M57m7pOiUigXrm3c0t9j04788xwmIcFVHhCs0dYWOMu3OMcPWzkqha9fBYu08WKScoqr/aAkJsuikljE6pU28+rWOV9/0eMWEM7QQOKF5hq0d2OzudfGEL3fPS7nj+LfBFm1u9mgzsJUWmcGjJKd+iqDYY8xwE5NqDk2NdT969oXHu8NrlpT/x+EfC/dW7ZHxsFjNa3p6/+LbVjyPTatdBU7DMIcPVg5dhfvNwJK9taKH7GhFU+wxZnti08yqoNEtzX/Ux7QyHyOTatYzaBjSnm+ljR+YgWr/b77HW/WTupwtdT7b/N4ernIp6wdpy2fSltXSjnVVF1qPb2cGrbbDpNaD67aIur84CqQDm6qGqAO/H9ufo2C71KyDlNDRXLQ+wR26mrUPnOUySovMIc+5u8zHHpP93lNJuKojwhVOdPklTm0/UKRvdxzU11uztX5btv7I8/3L3WKROiVGmT1b7sCVFFNNdTgAJybDqDRHrdBdbKTwCPuKKua2ucoqApMt2vwHvi3qkH3RZo/Ukf4vfbnT7OUqyTF7ckoOunt8csx9lZ9bQ9zBqVKQimllfk59cLnMwiX5WRXz9MLi3PPW0v33D19HgbnIefaWSpv7dU3mTlqsZsCKTjELnxwawJxF7iF/H/pezxoitRliBqpOY80qmzXhLJF2fW0Gra2rpd3fHtJDZzGDhOf3F5NqtiumlTlv8HgUZ/Hc66WF5n3tLZpTYAYF7/PCqucU/GGGqCP9rIPt5ndq3qGihyqmlfmefb+5q4v+Zv5PjsMFMYvVnB/ZvJN5v0U0N+e3ejf369DI4xtkSovMYaB5u92Pu8zH3EqvD+0x/stWvwdmwlUdEa4AX4ZhaGd2sb7elq317rC1ZX/VoUCp8WE6JT1ePVrFKL1ZhHdOF8MJASAAOYvNnq4Dv5u9CHm7K/5RnLvbrA56uN646oRESB1GSp3HSR3OqJ+5XiW50rYvzaC1ZbW0b+PR3xPe3B24Us0g6AliEQlmr5gjz+z1q+lWmi8ZrqN/7tFEtHCHpw6VglQHs501mbfoKjd/X/t/cy/pUOnRkVezNgTbzZ+PT/hyP7fHVFQVLS91b85qnh+yr6zE/J8J1QWnwwmJcIf1FGn8c+ZzPyJc1RHhCji6ffkObdiWbQaubdn6eU+eXIf52yQp2q60+HClxocrNT5MafHh3i0hyiYLE5MBIPC4XOZyAD69D7sr9UzsNv8h3v50M1C1HXr8qxfm/2H25OTuqn6ryRzBugjxLFge7ruoecghrz1bWLw7RLU3ezKPB8/wXU/Qyttj/t4K97sf3c+P98/Go3Jwim5Vfa+nPcbvQwErI1zVEeEKOHb5JU59uyNH67dm67c/8rXzYLF2HChUYemRJ1TbQ6xKjTODlyeApXmfhyk8lKqFAIB6YBjmENDc3ZUqPu6uCF6F+81QZIt2D0OttIVGVr/fFi3ZIs3jIeGBXUyitNAduPZLRYcEr8J95hDboGCz4mtQqFkEp7rn1mrOiWzhDlMtG11wqgnCVR0RroD6YRiGDhY5tSO7SDuyi7Qzu0g7DrifHyzSnpziw/Z2eTSPDK0IXnGVAlizcCVF2xVkDay/oAEAQGA5lmzA/xIGcNxYLBbFR4QqPiJUvVJjqxx3lru0J6fYG752HDBD185sc19usVP7C0q1v6BU3+3IqfL+kCCLWsaGKTU+XC1jw5QYbVdSjF1JlR5jw0MYdggAABoE4QqA34QEWZXeLELpzSKqPZ5b5HSHraKKAObuAdudUyxnuaFtB4q07UDRYT/DFmw1Q5cncMXYq7xuEWVTSFAAD+UAAACNAuEKQKMVEx6imPAYdW8ZU+VYuXuh5B0HzLCVmVuirLwSZeUWKyvPoT/ySpRdWCpHmcsbyg7HYpGaRdiUFGNTUnSY+9Hu7QlLdgeyKDvregEAgMNjzlU1mHMFNA2OsnLtzXMoK69Embkl+sMTwPIqnv+RVyJnec3+GowIDVKiZ9hhtF0tou1KjLapRZRdLaJtahFlPg8LpfQ8AABNBXOuAECSLTjIXf49/LDnuFyGsotKlZVrBi2z98u9ucNXVm6J8krKVFhari37CrVl35HL1UbZg9UiyqbEaHPIYYtDHlNiwpQca2coIgAATQzhCsAJzWq1qHmkTc0jbdUOP/QoKi07JHA5tDe/RHvz3I/55lDEEqdL+SVlyi8p0+9HCGFWi5QcE6bU+DCfKoie16z/BQBA4CFcAUANhIcGq21CpNomRB72HMMwlO8oMwNXnhm49uaX6I88h/ncvW9PTrEcZS7tzinW7pxifaXsKteyBVvVKi6sInTFhatVXJiSY8OUFG1XQpSNMvQAADQyhCsAqCcWi0XR9hBF20PUvsXhQ5jLZWhfgUM7sytKz1d+nplrhq/f9xUetvcryGrxDj1MjvEtQZ8cYwawxBibbMHM/wIAoKFQ0KIaFLQA4E/Ocpcyc0q8iy2bwatYuw4W6Y/cEv2R71D50VZfdouPCHUX37ApIdKmhKhKW6XXkbZghiECAFANCloAQAALCbIqrVm40ppVX4ij3GXoQIGjUvl5dzXEvBJl5hZ754aVOF3KLixVdmGpfs488mfagq3Vhq74iFBFhAYrwhasSFuwImxB7seKfQxPBADARLgCgAATZLWYlQej7ep5mHMMw1BusdNbhn5fvqNiKzAf97tf5zvK5ChzadfBYu06WHzM7bGHWCsCV6gZuKLswUqJNQt2tIqrmDMWGx5CDxkAoMkiXAFAE2SxWBQbHqrY8FB1TjryEIbi0nLtLzCLblQOX/vyHcopKlWBo0yFjjIVOsrN56Xma8/6YCVOl0qcpdpfUHrUdkXagtUqzgxcreLClBrvfowzKyWyUDMAIJARrgDgBBcWevT1wKrjKCtXoaNchY4yFVTaCh1lyi12are7J2znwSLtOlisffkOFTjK9EtWvn7Jyq/2mjFhIWoRZVNcRKjiwkMUHxGquHD35t4X594XHx6qKHuwrAxLBAA0EoQrAECt2IKDZAsOUnxEaI3OL3GW+4StXdlFPq+zC0uVW+xUbrGzxm0IsloUG2YGrvjwUDWLDFXzSJv3sXlkqJq51zFrFhmqKAp3AACOI8IVAKBB2EOC1L5F5GHL1Bc4yrT7YLH2Fzh0sKhUBwtLlV3oNJ8XlepgkdO9r1Q5RaUqLC03i3sUlupA4dGHJEpSaLBVzSM8gct8bBYZqmh7iKLsnvliId55Y5G2YEW6H23BVoIZAOCICFcAgEYh0hasTklR6qSoGp3vKCtXTpFT2YVm+DpQYAav/QUO7S8wHw8UOHSgsFT78x0qLC1XaZlLe3JLtCe35JjbFxJk8YatKFuIIu3Big8PVXKsXSkxYUqKsSsl1lxnrEWUTcFB1mP+DABAYCNcAQACki04SInRQUqMttfo/OLSch0oNIPXgQKHN4QdKChVgcOpAkeZ8kvMrcBRpoKSinlkkuQsN8zesyKnpCNXVbRapET3os4pMWFKjrErOTZMKe4FnxOj7Yq0Bys8JIgQBgBNiF/D1Zo1a/Too4/qm2++UWZmphYvXqwJEyYc8T0Oh0N/+9vf9PrrrysrK0utWrXSXXfdpSuuuMJ7zqJFi3TPPffo999/V7t27fTggw/q3HPPPc7fBgDQmIWFBqlVaLhaxR1b4Q6Xy1BhaUXgyvc8lpRpf4FDe3KLlZljrje2x73OWJnLUKZ7/bHvlHPE64cGWxURGqTw0GCFhwa5N/dzW7AiQoMUFhqkiNBghYUGyR4SJFuwVbZgq0KDrebctxCre1/Fscr7Q4OtsgcHUfwDAI4zv4arwsJC9ezZU5dffrkmTpxYo/dMmjRJf/zxh1566SW1b99ee/fuVVlZmff4unXrNHnyZN1///0699xztXjxYk2aNElffPGF+vfvf7y+CgCgibJaLYqyh5hl4mOOfr7LZbhDV4kyc4q1J7dEWbnF3teZuSXam+9QucssZV9a5lJpmcvdI3Z8Rdp855F555V5hzu6H93zzjz7otxz0qLDQhQRGsTcMwA4DIthGIa/GyGZa7Icredq6dKluvDCC7VlyxbFx8dXe87kyZOVl5enjz/+2Ltv9OjRiouL05tvvlmjtuTl5SkmJka5ubmKjj7y+jAAABwrwzBUWu5SkaNcRc5yFTnKVFRarsLSsir7iko9j2bZe0eZS44yc/6Yw7tVeu10qbTcJYezXI4yl8pc9fufeatFFWHL/RhlD1F0mPk6utLr2PBQNfdWbrQpnGAGIAAdSzYIqDlX77//vvr27atHHnlEr732miIiInTOOefo/vvvV1hYmCSz5+rPf/6zz/tGjRqluXPnHva6DodDDofD+zovL++4tB8AAMn8H4qeUvZxx/mzyl2GSstc3sWfPXPKzEdnlaGOlY9VnoOWV+xUmcuQy1ClkvlHnnt2KHuI1V0W36aEyFA1i7CpeZTn0abmEaFqHmVTfIRZwTE0mPloAAJLQIWrLVu26IsvvpDdbtfixYu1f/9+XXfddcrOztb8+fMlSVlZWUpMTPR5X2JiorKysg573Tlz5ui+++47rm0HAMAfgqwWhbnnbTWPtNX6OoZhqMTpUl6JU/klTuWVmIErv6TMva/M3F9c5j2eXVhqFhHJL1Wxs1wlTpe5xtnBmoWysJCgih6xMLNXLDosRDFhIe59lY9VvPb0phHOADS0gApXLpdLFotFb7zxhmJizIHvTzzxhM4//3w9++yz3t6rQ4ccGIZxxGEIM2fO1C233OJ9nZeXp9TU1OPwDQAACEwWS0VIq2mFxsoKHWU6UFCqfe4S+T5VG93l8g+4S+nnuOefFTvLVews1x95jqNcvXq2YKt3iGKUd8iibwDzPHoXo3YvSB1lD6YACIBjFlDhKjk5WS1btvQGK0nq0qWLDMPQrl271KFDByUlJVXppdq7d2+V3qzKbDabbLba/988AABwZBG2YEXYgpXW7OjVGstdhgrcPWK5xU7lFTuV5+4V891X5j1m7jN7zQpLyyXJnIPmDnDHKshqUVx4iOLCQ83Q5XmMMPfFR5ivY8PMgBYean6/iFDK6wMnsoAKV4MGDdI777yjgoICRUZGSpJ+++03Wa1WtWrVSpI0YMAALV++3Gfe1bJlyzRw4EC/tBkAABybIKtFMeEhigkPUW3GkZSVu7xzxyqGLHqGMbpfO8p8hjfmFTuVXVSqg4XmmmflLsO9GHXpMX++PcSqCE/YsgUr0maW14+0BSvCFuQOYe5jdvN4hPd4RTXHCJu5Fho9aEDg8Gu4Kigo0ObNm72vt27dqoyMDMXHxystLU0zZ87U7t279eqrr0qSLr74Yt1///26/PLLdd9992n//v26/fbbdcUVV3iHBN50000aMmSIHn74YY0fP17/+c9/tGLFCn3xxRd++Y4AAKBhBQdZFRseqtjw0Fq931FWrpwip7ILS3WwsNQdukqVXejUwaJSc3+Reyt0eouFOMvNyowlTpdKnKU6UHjswexQFovcQSzIHdTMNdA8a5p51z0LqbzOmbnGmT3YKltIxb7QYKtchiGXy3AXJzFU7qq0VTpW7j0ulbtcirAFKyHKrPqYEGVuUbZgqj8Ch/BrKfbPPvtMw4cPr7J/6tSpWrBggaZNm6Zt27bps88+8x775ZdfdMMNN+jLL79Us2bNNGnSJD3wwAPecCVJ7777ru6++25t2bLFu4jweeedV+N2UYodAAAcq9IylwodZnVFM3CZ5fMLHWUqdJfSL/C8du8rKCnzWaS64v3l3rXQGitbsNUbtLyhq1L4SoiyKT48VOGhQbKHBskeHKSQIAuBDAHnWLJBo1nnqjEhXAEAAH/yVGf0hLGCysGs1LOuWbkcTnN9sxL3umaOsnLvemfe52UV655ZLVKw1Sqr1Rx+GWS1KshiPrdaLAoOMh+DrBYFuR+tFosKSsu0L9+h/fkO7ct3KN9RVqvvFWS1KCwkSPaQINlDrAoLMYuk2N37wtz7PK/NHriK872PwZWOhwS5X5vPPYtjE+JQX5rsOlcAAAAngsrVGROiGl/RrRJnufblO7SvwAxbnm2/57X78WChWYbf0wlX7jK8QfF4Cg22qnlEqJpF2tQ80nxsFhmq5pXWVmsWGaqESJviIkIVckgREme5y7v2W757zbcC7zpwTvecvYp9nqUOEiJDvT15zSPN9dsiWDz7hEK4AgAAwDGxhwQpNT5cqfFHr/5oGIac5YZ7rbNyFZeWq6TMfPTsK3G6fF57zjHnr7kfy8rlcFbad8hxh3ufs9xcOHtPbon25JbU6PvEhptrpRWVliu/xClHmauuPyKvsJAgNY8K9QYu7zDKyFCFhwZ7fxaOsoqfQbGzXCWVnheXun8u7s1ZZqh5VKhSYsKUEhumlrHmY0qsXS1jw9Q80kYhFD9hWGA1GBYIAAAQmIpLy7W/wFw3zbuWWkGpDhSYi1ofKCj17ssudOhIU9vCPMMMPeui2YK9ww6j7CHeao+FjnL3NT09eOZnFLmXBWhoIUEWJceYYcs3fIUp0hYsyZBhSIZkPrrjgPe1zIOeH41nX8V7DPOY51zvdXyPe1JGaLBF9uAg2XyGdwZ5i67Yg62NegkDhgUCAADghBQWWvNeNZfLUE6xU/sLHMordio8NNi9sLQZoOr6D/5CR1ml0FV6SAAzw5dn3plnrlnFc2uVfWEhZnGQYKtFe/Mc2pNbrD05JdqTU+zdsvJK5Cw3tCO7SDuyi+rU/oYUbLV459TZgiseX7miX6McGns4hCsAAACckKxWi+IjzEWhjwfPWmfpzSKOy/WrU1bu0h/5Dm/Y2u0NXmYIK3aavWkWmXP7LO4XnkGEnn0Wi2SRRZWni/kcq3TcUnFCpffKO9fMWV5peKdnKGiZS6WVhl+Weefj+X6fQBvdSLgCAAAAmojgIKtauocCNnYul+Gtdlnirn7pO5euXNFhIf5u5jEhXAEAAABocFZrRVXMpqLxzhwDAAAAgABCuAIAAACAekC4AgAAAIB6QLgCAAAAgHpAuAIAAACAekC4AgAAAIB6QLgCAAAAgHpAuAIAAACAekC4AgAAAIB6QLgCAAAAgHpAuAIAAACAekC4AgAAAIB6QLgCAAAAgHpAuAIAAACAehDs7wY0RoZhSJLy8vL83BIAAAAA/uTJBJ6McCSEq2rk5+dLklJTU/3cEgAAAACNQX5+vmJiYo54jsWoSQQ7wbhcLu3Zs0dRUVGyWCz1cs28vDylpqZq586dio6Orpdr4sTB/YO64P5BbXHvoC64f1AXjen+MQxD+fn5SklJkdV65FlV9FxVw2q1qlWrVsfl2tHR0X6/QRC4uH9QF9w/qC3uHdQF9w/qorHcP0frsfKgoAUAAAAA1APCFQAAAADUA8JVA7HZbJo1a5ZsNpu/m4IAxP2DuuD+QW1x76AuuH9QF4F6/1DQAgAAAADqAT1XAAAAAFAPCFcAAAAAUA8IVwAAAABQDwhXAAAAAFAPCFcN5LnnnlObNm1kt9t18skn6/PPP/d3k9AIrVmzRuPGjVNKSoosFouWLFnic9wwDM2ePVspKSkKCwvTsGHD9NNPP/mnsWhU5syZo1NOOUVRUVFq0aKFJkyYoF9//dXnHO4fHM68efPUo0cP72KdAwYM0Mcff+w9zr2DmpozZ44sFotuvvlm7z7uHxzO7NmzZbFYfLakpCTv8UC8dwhXDWDhwoW6+eabddddd+m7777T4MGDNWbMGO3YscPfTUMjU1hYqJ49e+qZZ56p9vgjjzyiJ554Qs8884zWr1+vpKQknXHGGcrPz2/glqKxWb16tWbMmKGvvvpKy5cvV1lZmc4880wVFhZ6z+H+weG0atVKf//737VhwwZt2LBBp59+usaPH+/9Rwz3Dmpi/fr1euGFF9SjRw+f/dw/OJJu3bopMzPTu/3444/eYwF57xg47vr162dcc801Pvs6d+5s/PWvf/VTixAIJBmLFy/2vna5XEZSUpLx97//3buvpKTEiImJMZ5//nk/tBCN2d69ew1JxurVqw3D4P7BsYuLizNefPFF7h3USH5+vtGhQwdj+fLlxtChQ42bbrrJMAz+7sGRzZo1y+jZs2e1xwL13qHn6jgrLS3VN998ozPPPNNn/5lnnqm1a9f6qVUIRFu3blVWVpbPvWSz2TR06FDuJVSRm5srSYqPj5fE/YOaKy8v11tvvaXCwkINGDCAewc1MmPGDJ111lkaOXKkz37uHxzNpk2blJKSojZt2ujCCy/Uli1bJAXuvRPs7wY0dfv371d5ebkSExN99icmJiorK8tPrUIg8twv1d1L27dv90eT0EgZhqFbbrlFp512mrp37y6J+wdH9+OPP2rAgAEqKSlRZGSkFi9erK5du3r/EcO9g8N566239O2332r9+vVVjvF3D46kf//+evXVV9WxY0f98ccfeuCBBzRw4ED99NNPAXvvEK4aiMVi8XltGEaVfUBNcC/haK6//nr98MMP+uKLL6oc4/7B4XTq1EkZGRnKycnRokWLNHXqVK1evdp7nHsH1dm5c6duuukmLVu2THa7/bDncf+gOmPGjPE+P+mkkzRgwAC1a9dOr7zyik499VRJgXfvMCzwOGvevLmCgoKq9FLt3bu3ShIHjsRTPYd7CUdyww036P3339enn36qVq1aefdz/+BoQkND1b59e/Xt21dz5sxRz5499dRTT3Hv4Ii++eYb7d27VyeffLKCg4MVHBys1atX6+mnn1ZwcLD3HuH+QU1ERETopJNO0qZNmwL27x7C1XEWGhqqk08+WcuXL/fZv3z5cg0cONBPrUIgatOmjZKSknzupdLSUq1evZp7CTIMQ9dff73ee+89rVq1Sm3atPE5zv2DY2UYhhwOB/cOjmjEiBH68ccflZGR4d369u2rKVOmKCMjQ23btuX+QY05HA5t3LhRycnJAft3D8MCG8Att9yiSy+9VH379tWAAQP0wgsvaMeOHbrmmmv83TQ0MgUFBdq8ebP39datW5WRkaH4+HilpaXp5ptv1kMPPaQOHTqoQ4cOeuihhxQeHq6LL77Yj61GYzBjxgz9+9//1n/+8x9FRUV5/09fTEyMwsLCvOvOcP+gOnfeeafGjBmj1NRU5efn66233tJnn32mpUuXcu/giKKiorxzOz0iIiLUrFkz737uHxzObbfdpnHjxiktLU179+7VAw88oLy8PE2dOjVw/+7xW53CE8yzzz5rpKenG6GhoUafPn285ZGByj799FNDUpVt6tSphmGYZUlnzZplJCUlGTabzRgyZIjx448/+rfRaBSqu28kGS+//LL3HO4fHM4VV1zh/W9UQkKCMWLECGPZsmXe49w7OBaVS7EbBvcPDm/y5MlGcnKyERISYqSkpBjnnXee8dNPP3mPB+K9YzEMw/BTrgMAAACAJoM5VwAAAABQDwhXAAAAAFAPCFcAAAAAUA8IVwAAAABQDwhXAAAAAFAPCFcAAAAAUA8IVwAAAABQDwhXAAAAAFAPCFcAANQzi8WiJUuW+LsZAIAGRrgCADQp06ZNk8ViqbKNHj3a300DADRxwf5uAAAA9W306NF6+eWXffbZbDY/tQYAcKKg5woA0OTYbDYlJSX5bHFxcZLMIXvz5s3TmDFjFBYWpjZt2uidd97xef+PP/6o008/XWFhYWrWrJmuvvpqFRQU+Jwzf/58devWTTabTcnJybr++ut9ju/fv1/nnnuuwsPD1aFDB73//vvH90sDAPyOcAUAOOHcc889mjhxor7//ntdcskluuiii7Rx40ZJUlFRkUaPHq24uDitX79e77zzjlasWOETnubNm6cZM2bo6quv1o8//qj3339f7du39/mM++67T5MmTdIPP/ygsWPHasqUKcrOzm7Q7wkAaFgWwzAMfzcCAID6Mm3aNL3++uuy2+0++++44w7dc889slgsuuaaazRv3jzvsVNPPVV9+vTRc889p3/961+64447tHPnTkVEREiSPvroI40bN0579uxRYmKiWrZsqcsvv1wPPPBAtW2wWCy6++67df/990uSCgsLFRUVpY8++oi5XwDQhDHnCgDQ5AwfPtwnPElSfHy89/mAAQN8jg0YMEAZGRmSpI0bN6pnz57eYCVJgwYNksvl0q+//iqLxaI9e/ZoxIgRR2xDjx49vM8jIiIUFRWlvXv31vYrAQACAOEKANDkREREVBmmdzQWi0WSZBiG93l154SFhdXoeiEhIVXe63K5jqlNAIDAwpwrAMAJ56uvvqryunPnzpKkrl27KiMjQ4WFhd7jX375paxWqzp27KioqCi1bt1aK1eubNA2AwAaP3quAABNjsPhUFZWls++4OBgNW/eXJL0zjvvqG/fvjrttNP0xhtv6Ouvv9ZLL70kSZoyZYpmzZqlqVOnavbs2dq3b59uuOEGXXrppUpMTJQkzZ49W9dcc41atGihMWPGKD8/X19++aVuuOGGhv2iAIBGhXAFAGhyli5dquTkZJ99nTp10i+//CLJrOT31ltv6brrrlNSUpLeeOMNde3aVZIUHh6uTz75RDfddJNOOeUUhYeHa+LEiXriiSe815o6dapKSkr05JNP6rbbblPz5s11/vnnN9wXBAA0SlQLBACcUCwWixYvXqwJEyb4uykAgCaGOVcAAAAAUA8IVwAAAABQD5hzBQA4oTAaHgBwvNBzBQAAAAD1gHAFAAAAAPWAcAUAAAAA9YBwBQAAAAD1gHAFAAAAAPWAcAUAAAAA9YBwBQAAAAD1gHAFAAAAAPXg/wEJmMkcGpNTkgAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Calculate and print accuracies for training and cross-validation sets\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    # Training set accuracy\n",
    "    tr_correct = 0\n",
    "    tr_total = 0\n",
    "    for images, labels in trLoader:\n",
    "        outputs = model(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        _, true_labels = torch.max(labels, 1)\n",
    "        tr_total += labels.size(0)\n",
    "        tr_correct += (predicted == true_labels).sum().item()\n",
    "    \n",
    "    tr_accuracy = 100 * tr_correct / tr_total\n",
    "    \n",
    "    # Cross-validation set accuracy\n",
    "    cv_correct = 0\n",
    "    cv_total = 0\n",
    "    for images, labels in cvLoader:\n",
    "        outputs = model(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        _, true_labels = torch.max(labels, 1)\n",
    "        cv_total += labels.size(0)\n",
    "        cv_correct += (predicted == true_labels).sum().item()\n",
    "    \n",
    "    cv_accuracy = 100 * cv_correct / cv_total\n",
    "\n",
    "print(f'Accuracy on training set: {tr_accuracy:.2f}%')\n",
    "print(f'Accuracy on cross-validation set: {cv_accuracy:.2f}%')\n",
    "\n",
    "# Plot training and cross-validation losses\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(range(1, num_epochs+1), train_losses, label='Training Loss')\n",
    "plt.plot(range(1, num_epochs+1), cv_losses, label='Cross-Validation Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.title('Training and Cross-Validation Loss')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "21761e6d-6c8b-43d4-9f98-20bdb8e3489a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test set size: 10000\n",
      "Training set size: 60000\n",
      "Number of training samples: 43360\n",
      "Number of cross-validation samples: 10850\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "label_size = 18 # Label size\n",
    "ticklabel_size = 14 # Tick label size\n",
    "    \n",
    "# Define a transform to normalize the data\n",
    "transform = transforms.Compose([\n",
    "    transforms.ToTensor()\n",
    "])\n",
    "\n",
    "# Load test data from the MNIST\n",
    "testset = torchvision.datasets.MNIST(root='./Data', train=False, download=False, transform=transform)\n",
    "print(f\"Test set size: {len(testset)}\")\n",
    "\n",
    "# Load training data from the MNIST\n",
    "trainset = torchvision.datasets.MNIST(root='./Data', train=True, download=False, transform=transform)\n",
    "print(f\"Training set size: {len(trainset)}\")\n",
    "\n",
    "# Rate of trX and cvX\n",
    "tr_cv_rate = 0.8\n",
    "\n",
    "# Create a list to store indices for each class unique()\n",
    "class_indices = [[] for _ in range(10)]  # 10 classes in MNIST\n",
    "\n",
    "# Populate class_indices\n",
    "for idx, (_, label) in enumerate(trainset):\n",
    "    class_indices[label].append(idx)\n",
    "\n",
    "# Calculate the number of samples for each class in training and validation sets\n",
    "train_size_per_class = int(tr_cv_rate * min(len(indices) for indices in class_indices))\n",
    "val_size_per_class = min(len(indices) for indices in class_indices) - train_size_per_class\n",
    "\n",
    "# Create balanced train and validation sets\n",
    "train_indices = []\n",
    "val_indices = []\n",
    "for indices in class_indices:\n",
    "    train_indices.extend(indices[:train_size_per_class])\n",
    "    val_indices.extend(indices[train_size_per_class:train_size_per_class + val_size_per_class])\n",
    "\n",
    "# Create Subset datasets\n",
    "from torch.utils.data import Subset\n",
    "trX = Subset(trainset, train_indices)\n",
    "cvX = Subset(trainset, val_indices)\n",
    "\n",
    "print(f\"Number of training samples: {len(trX)}\")\n",
    "print(f\"Number of cross-validation samples: {len(cvX)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4bdf651e-dac7-43a6-b357-e91e274b573a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "image_channels is 1\n",
      "tensor([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]])\n"
     ]
    }
   ],
   "source": [
    "batch_size = 42 # Define training batch 1，\n",
    "\n",
    "def one_hot_collate(batch):\n",
    "    data = torch.stack([item[0] for item in batch])\n",
    "    labels = torch.tensor([item[1] for item in batch])\n",
    "    one_hot_labels = torch.zeros(labels.size(0), 10)  # 10 classes in MNIST 【0，1，0，0】\n",
    "    one_hot_labels.scatter_(1, labels.unsqueeze(1), 1)\n",
    "    return data, one_hot_labels\n",
    "\n",
    "trLoader = torch.utils.data.DataLoader(trX, batch_size=batch_size, shuffle=True, num_workers=0, collate_fn=one_hot_collate)\n",
    "cvLoader = torch.utils.data.DataLoader(cvX, batch_size=batch_size, shuffle=False, num_workers=0, collate_fn=one_hot_collate)\n",
    "teLoader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=0, collate_fn=one_hot_collate)\n",
    "\n",
    "# Get a batch of training data\n",
    "dataiter = iter(trLoader)\n",
    "data, labels = next(dataiter)\n",
    "\n",
    "image_channels = data[0].numpy().shape[0]\n",
    "print(f'image_channels is {image_channels}')\n",
    "print(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fb3d40ff-f95a-4a17-9f84-343e9948b4a0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN(\n",
      "  (conv1): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "  (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      "  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "  (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      "  (fc1): Linear(in_features=3136, out_features=100, bias=True)\n",
      "  (fc2): Linear(in_features=100, out_features=10, bias=True)\n",
      "  (softmax): Softmax(dim=1)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "\n",
    "class CNN(nn.Module):\n",
    "    def __init__(self, image_channels, num_classes):\n",
    "        super(CNN, self).__init__()\n",
    "        \n",
    "        # First convolutional layer\n",
    "        self.conv1 = nn.Conv2d(in_channels=image_channels, out_channels=32, kernel_size=3, padding=1)\n",
    "        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        \n",
    "        # Second convolutional layer\n",
    "        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n",
    "        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        \n",
    "        # Fully connected layers\n",
    "        self.fc1 = nn.Linear(64 * 7 * 7, 100)  # After two 2x2 max pools, 28x28 -> 7x7\n",
    "        self.fc2 = nn.Linear(100, num_classes)  # 10 classes output\n",
    "\n",
    "        # Softmax\n",
    "        self.softmax = nn.Softmax(dim=1)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # Remove the reshape operation and directly use x\n",
    "        x = F.relu(self.conv1(x))\n",
    "        x = self.pool1(x)\n",
    "        \n",
    "        # Second conv layer\n",
    "        x = F.relu(self.conv2(x))\n",
    "        x = self.pool2(x)\n",
    "        \n",
    "        # Flatten the output for the fully connected layers\n",
    "        x = x.view(-1, 64 * 7 * 7)\n",
    "        \n",
    "        # Fully connected layers\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        \n",
    "        # Softmax\n",
    "        x = self.softmax(x)\n",
    "        \n",
    "        return x\n",
    "\n",
    "# Initialize the model\n",
    "model = CNN(image_channels, 10)\n",
    "if torch.cuda.is_available():\n",
    "    model = model.cuda()\n",
    "\n",
    "# Display model architecture\n",
    "print(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9041c840-deb7-4663-bb25-0cdea23c5a0a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/50], Train Loss: 1.6850, CV Loss: 1.5879\n",
      "Epoch [2/50], Train Loss: 1.5819, CV Loss: 1.5807\n",
      "Epoch [3/50], Train Loss: 1.4982, CV Loss: 1.4838\n",
      "Epoch [4/50], Train Loss: 1.4780, CV Loss: 1.4808\n",
      "Epoch [5/50], Train Loss: 1.4748, CV Loss: 1.4815\n",
      "Epoch [6/50], Train Loss: 1.4728, CV Loss: 1.4817\n",
      "Epoch [7/50], Train Loss: 1.4712, CV Loss: 1.4766\n",
      "Epoch [8/50], Train Loss: 1.4702, CV Loss: 1.4791\n",
      "Epoch [9/50], Train Loss: 1.4701, CV Loss: 1.4779\n",
      "Epoch [10/50], Train Loss: 1.4688, CV Loss: 1.4792\n",
      "Epoch [11/50], Train Loss: 1.4680, CV Loss: 1.4784\n",
      "Epoch [12/50], Train Loss: 1.4680, CV Loss: 1.4783\n",
      "Epoch [13/50], Train Loss: 1.4672, CV Loss: 1.4764\n",
      "Epoch [14/50], Train Loss: 1.4680, CV Loss: 1.4776\n",
      "Epoch [15/50], Train Loss: 1.4672, CV Loss: 1.4772\n",
      "Epoch [16/50], Train Loss: 1.4667, CV Loss: 1.4753\n",
      "Epoch [17/50], Train Loss: 1.4662, CV Loss: 1.4768\n",
      "Epoch [18/50], Train Loss: 1.4658, CV Loss: 1.4774\n",
      "Epoch [19/50], Train Loss: 1.4671, CV Loss: 1.4766\n",
      "Epoch [20/50], Train Loss: 1.4663, CV Loss: 1.4765\n",
      "Epoch [21/50], Train Loss: 1.4655, CV Loss: 1.4752\n",
      "Epoch [22/50], Train Loss: 1.4660, CV Loss: 1.4768\n",
      "Epoch [23/50], Train Loss: 1.4664, CV Loss: 1.4766\n",
      "Epoch [24/50], Train Loss: 1.4652, CV Loss: 1.4767\n",
      "Epoch [25/50], Train Loss: 1.4658, CV Loss: 1.4766\n",
      "Epoch [26/50], Train Loss: 1.4656, CV Loss: 1.4766\n",
      "Epoch [27/50], Train Loss: 1.4653, CV Loss: 1.4846\n",
      "Epoch [28/50], Train Loss: 1.4654, CV Loss: 1.4782\n",
      "Epoch [29/50], Train Loss: 1.4654, CV Loss: 1.4793\n",
      "Epoch [30/50], Train Loss: 1.4648, CV Loss: 1.4758\n",
      "Epoch [31/50], Train Loss: 1.4659, CV Loss: 1.4761\n",
      "Epoch [32/50], Train Loss: 1.4658, CV Loss: 1.4757\n",
      "Epoch [33/50], Train Loss: 1.4657, CV Loss: 1.4761\n",
      "Epoch [34/50], Train Loss: 1.4658, CV Loss: 1.4746\n",
      "Epoch [35/50], Train Loss: 1.4644, CV Loss: 1.4758\n",
      "Epoch [36/50], Train Loss: 1.4649, CV Loss: 1.4765\n",
      "Epoch [37/50], Train Loss: 1.4651, CV Loss: 1.4785\n",
      "Epoch [38/50], Train Loss: 1.4655, CV Loss: 1.4755\n",
      "Epoch [39/50], Train Loss: 1.4654, CV Loss: 1.4761\n",
      "Epoch [40/50], Train Loss: 1.4661, CV Loss: 1.4751\n",
      "Epoch [41/50], Train Loss: 1.4647, CV Loss: 1.4773\n",
      "Epoch [42/50], Train Loss: 1.4650, CV Loss: 1.4747\n",
      "Epoch [43/50], Train Loss: 1.4647, CV Loss: 1.4778\n",
      "Epoch [44/50], Train Loss: 1.4643, CV Loss: 1.4763\n",
      "Epoch [45/50], Train Loss: 1.4660, CV Loss: 1.4747\n",
      "Epoch [46/50], Train Loss: 1.4654, CV Loss: 1.4758\n",
      "Epoch [47/50], Train Loss: 1.4651, CV Loss: 1.4759\n",
      "Epoch [48/50], Train Loss: 1.4645, CV Loss: 1.4751\n",
      "Epoch [49/50], Train Loss: 1.4654, CV Loss: 1.4775\n",
      "Epoch [50/50], Train Loss: 1.4650, CV Loss: 1.4731\n"
     ]
    }
   ],
   "source": [
    "# Define loss function and optimizer\n",
    "criterion = nn.CrossEntropyLoss() # Loss\n",
    "optimizer = torch.optim.Adam(model.parameters()) # Adam\n",
    "\n",
    "# Lists to store losses\n",
    "train_losses = []\n",
    "cv_losses = []\n",
    "\n",
    "# Number of epochs\n",
    "num_epochs = 50\n",
    "\n",
    "for epoch in range(num_epochs):\n",
    "    model.train()\n",
    "    batch_losses = []\n",
    "    \n",
    "    for batch_x, batch_y in trLoader:\n",
    "        # Forward pass\n",
    "        outputs = model(batch_x)\n",
    "        loss = criterion(outputs, batch_y)\n",
    "        \n",
    "        # Backward pass and optimize\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "        batch_losses.append(loss.item())\n",
    "    \n",
    "    # Calculate average training loss for this epoch\n",
    "    avg_train_loss = sum(batch_losses) / len(batch_losses)\n",
    "    train_losses.append(avg_train_loss)\n",
    "    \n",
    "    # Evaluate on cross-validation set\n",
    "    model.eval()\n",
    "    cv_batch_losses = []\n",
    "    with torch.no_grad():\n",
    "        for cv_x, cv_y in cvLoader:\n",
    "            cv_outputs = model(cv_x)\n",
    "            cv_loss = criterion(cv_outputs, cv_y)\n",
    "            cv_batch_losses.append(cv_loss.item())\n",
    "    \n",
    "    avg_cv_loss = sum(cv_batch_losses) / len(cv_batch_losses)\n",
    "    cv_losses.append(avg_cv_loss)\n",
    "    \n",
    "    print(f'Epoch [{epoch+1}/{num_epochs}], Train Loss: {avg_train_loss:.4f}, CV Loss: {avg_cv_loss:.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c5a2d115-bda3-4edf-8a1d-fbabb943b259",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on training set: 99.76%\n",
      "Accuracy on cross-validation set: 98.79%\n"
     ]
    },
    {
     "data": {
      "image/png": "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n/WeKlll+fn5uvPOO9WlSxcFBQUpKChIkZGRKigoqPXzeniqPYe/97/73e8UERHhfe896vM7UpO2RERE6IILLvBZ72mbpy0DBw6UJE2ZMkXvvfeedu/eXeWxBg0apHXr1un666/XF198odzc3Hq3D0DzQLgCgMOkpKRUWZefn69hw4bp3//+tx566CF9+eWXWrNmjT788ENJOuqkCh4JCQlV1jkcjhrdNzw8XKGhoVXuW1xc7L2dmZmp1q1bV7lvdeuq89RTT+kPf/iDTjnlFC1YsEDfffed1qxZo7Fjx1bbxsNfj6d7l2ffzMxMSVJycnKV+1a37nCeD9lbt26tUfs9Dv/5edpR3c+1TZs23u2GYWjZsmU666yz9Pjjj6t///5KSkrSH//4R+Xl5Umyur8tXbpUrVq10g033KDOnTurc+fOPmNtRo8ereDgYO/iCU6GYeiqq67S+vXrtXbtWklWl8COHTtq1KhRkhrmODv8tVf386/u/b/kkkv03HPP6eqrr9YXX3yh77//XmvWrFFSUlKtn7fy8wcFBfl0g5Ss9yI5Odn73nvU53ekJm1JTk6uMh6yVatWCgoK8rZl+PDh+uijj1RWVqYrrrhC7dq10wknnKB33nnHe5+77rpLTzzxhL777juNGzdOCQkJGj16tPfnCqDlYswVABymunNULV++XHv27NGXX37prSJIalJjLBISEvT9999XWV/d5AXVeeuttzRy5EjNmTPHZ70nWNSlPUd6/pq0adSoUQoODtZHH32k6667rsbPe/jPz9OOvXv3Vtl3z549SkxM9N5OS0vTq6++Kkn63//+p/fee08zZ85USUmJXnzxRUnSsGHDNGzYMJWXl2vt2rX629/+pltuuUWtW7fWRRddpL///e8+71nlx582bZruv/9+vfbaawoODtaPP/6oBx980Nvmhj7OanpM5OTk6JNPPtGMGTN8zsfldDq9Y/Hq+vxlZWVVxpmZpqmMjAxvlagxJCQk6N///rdM0/Q5Rvbv36+ysjKfn9PEiRM1ceJEOZ1Offfdd5o1a5YuueQSdejQQYMHD1ZQUJBuvfVW3XrrrcrOztbSpUt1991366yzztLOnTtrNbsogOaFyhUA1IDnw1jlwfeS9Pe//90fzanWiBEjlJeXp88//9xn/bvvvluj+xuGUeX1/fTTT1XOD1ZT3bt3V0pKit555x2Zpuldv337dq1ateqY909OTvZWUY40w+Bvv/2mn3766aiPM3jwYIWFhemtt97yWb9r1y4tX75co0ePrvZ+3bp107333qsTTzxRP/zwQ5Xtdrtdp5xyip5//nlJ8u7TvXt3DRgwwLtUnj2vTZs2Gjt2rN555x09//zzstlsmjp1qnd7Qx9no0aNUl5enj7++GOf9f/4xz98bhuGIdM0qzzvK6+8ovLycp91h1coj8bz3h7+3i9YsEAFBQVHfO+Ph9GjRys/P18fffSRz3rPsVVdWxwOh0aMGKHHHntMkvTjjz9W2Sc2NlYXXHCBbrjhBmVlZVV7cmUALQeVKwCogSFDhiguLk7XXXedZsyYoeDgYL399ttat26dv5vmNXXqVD399NO67LLL9NBDD6lLly76/PPP9cUXX0jSMWfnO+ecc/Tggw9qxowZGjFihDZt2qS//OUv6tixo8rKymrdHpvNpgcffFBXX321zjvvPF1zzTXKzs7WzJkza9QtULK6Km7ZskXTpk3TF198ofPOO0+tW7fWwYMHtWTJEs2dO1fvvvuud7xXdWJjY3Xffffp7rvv1hVXXKGLL75YmZmZeuCBBxQaGqoZM2ZIsoLkjTfeqN/97nfq2rWrQkJCtHz5cv3000/eas6LL76o5cuX6+yzz1ZqaqqKi4u9U4WPGTOmRq9p+vTp+vTTT73TzLdv3967raGPsyuuuEJPP/20rrjiCj388MPq2rWrPvvsM+8x4REdHa3hw4frr3/9qxITE9WhQwd99dVXevXVVxUbG+uz7wknnCBJeumllxQVFaXQ0FB17Nix2i59Z5xxhs466yzdeeedys3N1dChQ72zBfbr10+XX355nV7Xkfz222/64IMPqqzv1auXrrjiCj3//POaOnWqtm3bphNPPFHffPONHnnkEY0fP97787v//vu1a9cujR49Wu3atVN2draeeeYZn7FvEyZM0AknnKABAwYoKSlJ27dv1+zZs5WWluadeRJAC+Xf+TQAwH+ONFtg7969q91/1apV5uDBg83w8HAzKSnJvPrqq80ffvihyqxrR5ot8Oyzz67ymIfP7nak2QIPb+eRnmfHjh3m+eefb0ZGRppRUVHm5MmTzc8++6zaGeMO53Q6zdtvv91s27atGRoaavbv39/86KOPqswA55kt8K9//WuVx5Bkzpgxw2fdK6+8Ynbt2tUMCQkxu3XrZr722mtVHvNoysrKzNdff908/fTTzfj4eDMoKMhMSkoyx40bZ/7jH/8wy8vLTdOseO/ef//9ah/nlVdeMfv06WOGhISYMTEx5sSJE82ff/7Zu33fvn3mtGnTzB49epgRERFmZGSk2adPH/Ppp5/2zoq4evVq87zzzjPT0tJMh8NhJiQkmCNGjDA//vjjGr0W0zTNkpISs3Xr1tXOXGea9TvODj+eTNM0d+3aZU6ePNnnmFi1alWVx/PsFxcXZ0ZFRZljx441//vf/5ppaWnm1KlTfR5z9uzZZseOHU273e7zONX9XIuKisw777zTTEtLM4ODg82UlBTzD3/4g3no0CGf/Wr6O3Ikko64eI7JzMxM87rrrjNTUlLMoKAgMy0tzbzrrrvM4uJi7+N88skn5rhx48y2bduaISEhZqtWrczx48ebX3/9tXefJ5980hwyZIiZmJhohoSEmKmpqeb06dPNbdu2HbOdAJo3wzQr9dUAADQ7jzzyiO69917t2LFD7dq183dzAABotugWCADNyHPPPSdJ6tGjh0pLS7V8+XI9++yzuuyyywhWAAAcZ4QrAGhGwsPD9fTTT2vbtm1yOp1KTU3VnXfeqXvvvdffTQMAoNmjWyAAAAAANACmYgcAAACABkC4AgAAAIAGQLgCAAAAgAbAhBbVcLlc2rNnj6KiomQYhr+bAwAAAMBPTNNUXl6e2rRpI5vt6LUpwlU19uzZo/bt2/u7GQAAAACaiJ07dx7ztCaEq2pERUVJst7A6OhoP7cGAAAAgL/k5uaqffv23oxwNISrani6AkZHRxOuAAAAANRouBATWgAAAABAAyBcAQAAAEADIFwBAAAAQANgzBUAAEALZ5qmysrKVF5e7u+mAH4RHBwsu91e78chXAEAALRgJSUl2rt3rwoLC/3dFMBvDMNQu3btFBkZWa/HIVwBAAC0UC6XS1u3bpXdblebNm0UEhJSoxnRgObENE0dOHBAu3btUteuXetVwSJcAQAAtFAlJSVyuVxq3769wsPD/d0cwG+SkpK0bds2lZaW1itcMaEFAABAC2ez8ZEQLVtDVWz5TQIAAACABkC4AgAAAIAGQLgCAABAizdy5EjdcsstNd5/27ZtMgxD6enpx61NCDyEKwAAAAQMwzCOukybNq1Oj/vhhx/qwQcfrPH+7du31969e3XCCSfU6flqihAXWJgtEAAAAAFj79693uvz58/X/fffr02bNnnXhYWF+exfWlqq4ODgYz5ufHx8rdpht9uVnJxcq/ug+aNy1cS9vHKLznp6pV79Zqu/mwIAAJo50zRVWFLml8U0zRq1MTk52bvExMTIMAzv7eLiYsXGxuq9997TyJEjFRoaqrfeekuZmZm6+OKL1a5dO4WHh+vEE0/UO++84/O4h3cL7NChgx555BFdddVVioqKUmpqql566SXv9sMrSl9++aUMw9CyZcs0YMAAhYeHa8iQIT7BT5IeeughtWrVSlFRUbr66qv15z//WSeddFKdfl6S5HQ69cc//lGtWrVSaGioTjvtNK1Zs8a7/dChQ7r00kuVlJSksLAwde3aVXPnzpVkTcV/4403KiUlRaGhoerQoYNmzZpV57aAylWTl11Uok378rQjs8DfTQEAAM1cUWm5et3/hV+ee8NfzlJ4SMN8NL3zzjv15JNPau7cuXI4HCouLtbJJ5+sO++8U9HR0fr00091+eWXq1OnTjrllFOO+DhPPvmkHnzwQd1999364IMP9Ic//EHDhw9Xjx49jnife+65R08++aSSkpJ03XXX6aqrrtK3334rSXr77bf18MMP64UXXtDQoUP17rvv6sknn1THjh3r/Fr/9Kc/acGCBXr99deVlpamxx9/XGeddZZ+/fVXxcfH67777tOGDRv0+eefKzExUb/++quKiookSc8++6w+/vhjvffee0pNTdXOnTu1c+fOOrcFhKsmLyHCIUk6mF/i55YAAAAEhltuuUXnn3++z7rbb7/de/2mm27SokWL9P777x81XI0fP17XX3+9JCuwPf300/ryyy+PGq4efvhhjRgxQpL05z//WWeffbaKi4sVGhqqv/3tb5o+fbquvPJKSdL999+vxYsXKz8/v06vs6CgQHPmzNG8efM0btw4SdLLL7+sJUuW6NVXX9Udd9yhHTt2qF+/fhowYIAkqyLnsWPHDnXt2lWnnXaaDMNQWlpandqBCoSrJi4xyhOunH5uCQAAaO7Cgu3a8Jez/PbcDcUTJDzKy8v16KOPav78+dq9e7ecTqecTqciIiKO+jh9+vTxXvd0P9y/f3+N75OSkiJJ2r9/v1JTU7Vp0yZvWPMYNGiQli9fXqPXdbjffvtNpaWlGjp0qHddcHCwBg0apI0bN0qS/vCHP2jy5Mn64YcfdOaZZ2rSpEkaMmSIJGnatGk644wz1L17d40dO1bnnHOOzjzzzDq1BRbCVROXGBEiiXAFAACOP8MwGqxrnj8dHpqefPJJPf3005o9e7ZOPPFERURE6JZbblFJydF7Bh0+EYZhGHK5XDW+j2EYkuRzH886j5qONauO577VPaZn3bhx47R9+3Z9+umnWrp0qUaPHq0bbrhBTzzxhPr376+tW7fq888/19KlSzVlyhSNGTNGH3zwQZ3b1NIxoUUT56lcZRbQLRAAAKAuvv76a02cOFGXXXaZ+vbtq06dOmnz5s2N3o7u3bvr+++/91m3du3aOj9ely5dFBISom+++ca7rrS0VGvXrlXPnj2965KSkjRt2jS99dZbmj17ts/EHNHR0brwwgv18ssva/78+VqwYIGysrLq3KaWLvC/mmjmEtyVq+zCUpWWuxRsJw8DAADURpcuXbRgwQKtWrVKcXFxeuqpp5SRkeETQBrDTTfdpGuuuUYDBgzQkCFDNH/+fP3000/q1KnTMe97+KyDktSrVy/94Q9/0B133KH4+Hilpqbq8ccfV2FhoaZPny7JGtd18sknq3fv3nI6nfrkk0+8r/vpp59WSkqKTjrpJNlsNr3//vtKTk5WbGxsg77uloRw1cTFhYfIZkguU8oqKFHr6FB/NwkAACCg3Hfffdq6davOOusshYeH69prr9WkSZOUk5PTqO249NJLtWXLFt1+++0qLi7WlClTNG3atCrVrOpcdNFFVdZt3bpVjz76qFwuly6//HLl5eVpwIAB+uKLLxQXFydJCgkJ0V133aVt27YpLCxMw4YN07vvvitJioyM1GOPPabNmzfLbrdr4MCB+uyzz2Sz8WV+XRlmfTp6NlO5ubmKiYlRTk6OoqOj/d0cDXhoqQ7mO/XJTafphLYx/m4OAABoJoqLi7V161Z17NhRoaF8gesPZ5xxhpKTk/Xmm2/6uykt2tF+F2qTDahcBYDEyBAdzHcy7goAACCAFRYW6sUXX9RZZ50lu92ud955R0uXLtWSJUv83TQ0EMJVAEiMdEjK08E8ZgwEAAAIVIZh6LPPPtNDDz0kp9Op7t27a8GCBRozZoy/m4YGQrgKAImR1qQWmQWEKwAAgEAVFhampUuX+rsZOI4YrRYAEiI9JxKmWyAAAADQVBGuAkCiN1xRuQIAAACaKsJVAEhwdwukcgUAAAA0XYSrAJDkrlxlUrkCAAAAmizCVQCoqFwRrgAAAICminAVABK9lasScc5nAAAAoGkiXAWA+AirclXmMpVTVOrn1gAAAKCxjBw5Urfccov3docOHTR79uyj3scwDH300Uf1fu6GepyWhHAVAEKD7YoKtU5JRtdAAAAAKSMjQzfddJM6deokh8Oh9u3ba8KECVq2bJm/myZJmjBhwhFPDrx69WoZhqEffvih1o+7Zs0aXXvttfVtno+ZM2fqpJNOqrJ+7969GjduXIM+1+HmzZun2NjY4/ocjYlwFSASOdcVAACAJGnbtm06+eSTtXz5cj3++ONav369Fi1apFGjRumGG2444v1KSxuvB9D06dO1fPlybd++vcq21157TSeddJL69+9f68dNSkpSeHh4QzTxmJKTk+VwOBrluZoLwlWASGRSCwAAcLyZplRS4J+lFuPKr7/+ehmGoe+//14XXHCBunXrpt69e+vWW2/Vd999593PMAy9+OKLmjhxoiIiIvTQQw9JkubMmaPOnTsrJCRE3bt315tvvunz+DNnzlRqaqocDofatGmjP/7xj95tL7zwgrp27arQ0FC1bt1aF1xwQbVtPOecc9SqVSvNmzfPZ31hYaHmz5+v6dOnKzMzUxdffLHatWun8PBwnXjiiXrnnXeO+toP7xa4efNmDR8+XKGhoerVq5eWLFlS5T533nmnunXrpvDwcHXq1En33XefN2jOmzdPDzzwgNatWyfDMGQYhrfNh3cLXL9+vU4//XSFhYUpISFB1157rfLz873bp02bpkmTJumJJ55QSkqKEhISdMMNN9Qr1O7YsUMTJ05UZGSkoqOjNWXKFO3bt8+7fd26dRo1apSioqIUHR2tk08+WWvXrpUkbd++XRMmTFBcXJwiIiLUu3dvffbZZ3VuS00EHddHR4NJiKiY1AIAAOC4KC2UHmnjn+e+e48UEnHM3bKysrRo0SI9/PDDioiouv/hXcxmzJihWbNm6emnn5bdbtfChQt18803a/bs2RozZow++eQTXXnllWrXrp1GjRqlDz74QE8//bTeffdd9e7dWxkZGVq3bp0kae3atfrjH/+oN998U0OGDFFWVpa+/vrratsZFBSkK664QvPmzdP9998vwzAkSe+//75KSkp06aWXqrCwUCeffLLuvPNORUdH69NPP9Xll1+uTp066ZRTTjnme+FyuXT++ecrMTFR3333nXJzc33GZ3lERUVp3rx5atOmjdavX69rrrlGUVFR+tOf/qQLL7xQ//3vf7Vo0SItXbpUkhQTE1PlMQoLCzV27FideuqpWrNmjfbv36+rr75aN954o0+AXLFihVJSUrRixQr9+uuvuvDCC3XSSSfpmmuuOebrOZxpmpo0aZIiIiL01VdfqaysTNdff70uvPBCffnll5KkSy+9VP369dOcOXNkt9uVnp6u4OBgSdINN9ygkpISrVy5UhEREdqwYYMiIyNr3Y7aIFwFiMQoKlcAAAC//vqrTNNUjx49arT/JZdcoquuusrn9rRp03T99ddLkrfa9cQTT2jUqFHasWOHkpOTNWbMGAUHBys1NVWDBg2SZFVRIiIidM455ygqKkppaWnq16/fEZ/7qquu0l//+ld9+eWXGjVqlCSrS+D555+vuLg4xcXF6fbbb/fuf9NNN2nRokV6//33axSuli5dqo0bN2rbtm1q166dJOmRRx6pMk7q3nvv9V7v0KGDbrvtNs2fP19/+tOfFBYWpsjISAUFBSk5OfmIz/X222+rqKhIb7zxhjfUPvfcc5owYYIee+wxtW7dWpIUFxen5557Tna7XT169NDZZ5+tZcuW1SlcLV26VD/99JO2bt2q9u3bS5LefPNN9e7dW2vWrNHAgQO1Y8cO3XHHHd7joWvXrt7779ixQ5MnT9aJJ54oSerUqVOt21BbhKsA4alcMeYKAAAcN8HhVgXJX89dA57T0ngqQccyYMAAn9sbN26sMiHE0KFD9cwzz0iSfve732n27Nnq1KmTxo4dq/Hjx2vChAkKCgrSGWecobS0NO+2sWPH6rzzzlN4eLjefvtt/f73v/c+5ueff65hw4ZpyJAheu211zRq1Cj99ttv+vrrr7V48WJJUnl5uR599FHNnz9fu3fvltPplNPprLYiV52NGzcqNTXVG6wkafDgwVX2++CDDzR79mz9+uuvys/PV1lZmaKjo2v0HJWfq2/fvj5tGzp0qFwulzZt2uQNV71795bdbvfuk5KSovXr19fquSo/Z/v27b3BSpJ69eql2NhYbdy4UQMHDtStt96qq6++Wm+++abGjBmj3/3ud+rcubMk6Y9//KP+8Ic/aPHixRozZowmT56sPn361KktNcWYqwCRGOUJV1SuAADAcWIYVtc8fyw1DEtdu3aVYRjauHFjjfavLqgcHsxM0/Sua9++vTZt2qTnn39eYWFhuv766zV8+HCVlpYqKipKP/zwg9555x2lpKTo/vvvV9++fZWdna1zzz1X6enp3sUT6qZPn64FCxYoNzdXc+fOVVpamkaPHi1JevLJJ/X000/rT3/6k5YvX6709HSdddZZKimp2Zfp1Z3/9PDX9t133+miiy7SuHHj9Mknn+jHH3/UPffcU+PnqO49OtpzerrkVd7mcrlq9VzHes7K62fOnKmff/5ZZ599tpYvX65evXpp4cKFkqSrr75aW7Zs0eWXX67169drwIAB+tvf/lanttQU4SpAJLrPdZVJuAIAAC1YfHy8zjrrLD3//PMqKCiosj07O/uo9+/Zs6e++eYbn3WrVq1Sz549vbfDwsJ07rnn6tlnn9WXX36p1atXe6svQUFBGjNmjB5//HH99NNP2rZtm5YvX66oqCh16dLFu4SFhUmSpkyZIrvdrn/84x96/fXXdeWVV3qDwddff62JEyfqsssuU9++fdWpUydt3ry5xu9Fr169tGPHDu3ZU1FtXL16tc8+3377rdLS0nTPPfdowIAB6tq1a5UZDENCQlReXn7M50pPT/d5z7/99lvZbDZ169atxm2uDc/r27lzp3fdhg0blJOT4/Pz6tatm/7v//5Pixcv1vnnn6+5c+d6t7Vv317XXXedPvzwQ9122216+eWXj0tbPegWGCAqKld0CwQAAC3bCy+8oCFDhmjQoEH6y1/+oj59+qisrExLlizRnDlzjlrVuuOOOzRlyhT1799fo0eP1r/+9S99+OGH3skc5s2bp/Lycp1yyikKDw/Xm2++qbCwMKWlpemTTz7Rli1bNHz4cMXFxemzzz6Ty+VS9+7dj/h8kZGRuvDCC3X33XcrJydH06ZN827r0qWLFixYoFWrVikuLk5PPfWUMjIyfILD0YwZM0bdu3fXFVdcoSeffFK5ubm65557fPbp0qWLduzYoXfffVcDBw7Up59+6q3seHTo0EFbt25Venq62rVrp6ioqCpTsF966aWaMWOGpk6dqpkzZ+rAgQO66aabdPnll3u7BNZVeXm50tPTfdaFhIRozJgx6tOnjy699FLNnj3bO6HFiBEjNGDAABUVFemOO+7QBRdcoI4dO2rXrl1as2aNJk+eLEm6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VFSUd2ynR0REhBISErzrOX5wJLfffrsmTJig1NRU7d+/Xw899JByc3M1derUwP3b47d5CluY559/3kxLSzNDQkLM/v37e6dHBipbsWKFKanKMnXqVNM0rWlJZ8yYYSYnJ5sOh8McPny4uX79ev82Gk1CdceNJHPu3LnefTh+cCRXXXWV939UUlKSOXr0aHPx4sXe7Rw7qI3KU7GbJscPjuzCCy80U1JSzODgYLNNmzbm+eefb/7888/e7YF47BimaZp+ynUAAAAA0Gww5goAAAAAGgDhCgAAAAAaAOEKAAAAABoA4QoAAAAAGgDhCgAAAAAaAOEKAAAAABoA4QoAAAAAGgDhCgAAAAAaAOEKAIAGZhiGPvroI383AwDQyAhXAIBmZdq0aTIMo8oyduxYfzcNANDMBfm7AQAANLSxY8dq7ty5PuscDoefWgMAaCmoXAEAmh2Hw6Hk5GSfJS4uTpLVZW/OnDkaN26cwsLC1LFjR73//vs+91+/fr1OP/10hYWFKSEhQddee63y8/N99nnttdfUu3dvORwOpaSk6MYbb/TZfvDgQZ133nkKDw9X165d9fHHHx/fFw0A8DvCFQCgxbnvvvs0efJkrVu3Tpdddpkuvvhibdy4UZJUWFiosWPHKi4uTmvWrNH777+vpUuX+oSnOXPm6IYbbtC1116r9evX6+OPP1aXLl18nuOBBx7QlClT9NNPP2n8+PG69NJLlZWV1aivEwDQuAzTNE1/NwIAgIYybdo0vfXWWwoNDfVZf+edd+q+++6TYRi67rrrNGfOHO+2U089Vf3799cLL7ygl19+WXfeead27typiIgISdJnn32mCRMmaM+ePWrdurXatm2rK6+8Ug899FC1bTAMQ/fee68efPBBSVJBQYGioqL02WefMfYLAJoxxlwBAJqdUaNG+YQnSYqPj/deHzx4sM+2wYMHKz09XZK0ceNG9e3b1xusJGno0KFyuVzatGmTDMPQnj17NHr06KO2oU+fPt7rERERioqK0v79++v6kgAAAYBwBQBodiIiIqp00zsWwzAkSaZpeq9Xt09YWFiNHi84OLjKfV0uV63aBAAILIy5AgC0ON99912V2z169JAk9erVS+np6SooKPBu//bbb2Wz2dStWzdFRUWpQ4cOWrZsWaO2GQDQ9FG5AgA0O06nUxkZGT7rgoKClJiYKEl6//33NWDAAJ122ml6++239f333+vVV1+VJF166aWaMWOGpk6dqpkzZ+rAgQO66aabdPnll6t169aSpJkzZ+q6665Tq1atNG7cOOXl5enbb7/VTTfd1LgvFADQpBCuAADNzqJFi5SSkuKzrnv37vrll18kWTP5vfvuu7r++uuVnJyst99+W7169ZIkhYeH64svvtDNN9+sgQMHKjw8XJMnT9ZTTz3lfaypU6equLhYTz/9tG6//XYlJibqggsuaLwXCABokpgtEADQohiGoYULF2rSpEn+bgoAoJlhzBUAAAAANADCFQAAAAA0AMZcAQBaFHrDAwCOFypXAAAAANAACFcAAAAA0AAIVwAAAADQAAhXAAAAANAACFcAAAAA0AAIVwAAAADQAAhXAAAAANAACFcAAAAA0AD+H/9/1uMwVm0UAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Calculate and print accuracies for training and cross-validation sets\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    # Training set accuracy\n",
    "    tr_correct = 0\n",
    "    tr_total = 0\n",
    "    for images, labels in trLoader:\n",
    "        outputs = model(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        _, true_labels = torch.max(labels, 1)\n",
    "        tr_total += labels.size(0)\n",
    "        tr_correct += (predicted == true_labels).sum().item()\n",
    "    \n",
    "    tr_accuracy = 100 * tr_correct / tr_total\n",
    "    \n",
    "    # Test set accuracy\n",
    "    cv_correct = 0\n",
    "    cv_total = 0\n",
    "    for images, labels in cvLoader:\n",
    "        outputs = model(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        _, true_labels = torch.max(labels, 1)\n",
    "        cv_total += labels.size(0)\n",
    "        cv_correct += (predicted == true_labels).sum().item()\n",
    "    \n",
    "    cv_accuracy = 100 * cv_correct / cv_total\n",
    "\n",
    "print(f'Accuracy on training set: {tr_accuracy:.2f}%')\n",
    "print(f'Accuracy on cross-validation set: {cv_accuracy:.2f}%')\n",
    "\n",
    "# Plot training and cross-validation losses\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(range(1, num_epochs+1), train_losses, label='Training Loss')\n",
    "plt.plot(range(1, num_epochs+1), cv_losses, label='Cross-Validation Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.title('Training and Cross-Validation Loss')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
